linux中C语言write,C语言fread/fwrite填坑记

先说结论

用fread或fwrite的时候,如果是要写入字符,那么打开的文件、读取的文件,用字符模式(w和r)

FILE* fin = fopen("filename", "w");

fread(buf, sizeof(char)*num_elem, 1, fin);

fclose(fin);

FILE *fout = fopen("filename", "r");

fwrite(buf, sizeof(char)*num_elem, 1, fout);

fclose(fout);

如果是要写入非字符的数据,例如float数组、int数组等,则一定要用二进制模式打开文件(wb和rb)(尽管在Linux和mac下你的结果也许一直没问题,但是保不准到了windows下会出错):

FILE* fin = fopen("filename", "wb");

fread(buf, sizeof(float)*num_elem, 1, fin);

fclose(fin);

FILE *fout = fopen("filename", "rb");

fwrite(buf, sizeof(float)*num_elem, 1, fout);

fclose(fout);

原因:字符模式打开的文件,在windows下,遇到0x0D和0x0A(分别是\r和\n)会替换为0x0A进行写入(也就是\n)。

举例细说

读取图像,通常用opencv,但是考虑到arm上用opencv过于庞大,考虑在pc上把图像的数据读取出来,然后整理下顺序,再用fwrite保存。后面在arm上直接fread就行了,避开了opencv。

但在具体实现的时候发现,fwrite后再fread,只有前面一部分数据是正确的!原因如上面说的,保存到文件的是float数组,但是打开文件的模式错误的设定为了字符模式,而不是二进制模式。

#include

#include

#include

#include

#include

#include

using namespace std;

using namespace cv;

int main() {

string im_pth = "../cat_227.jpg";

IplImage* img = cvLoadImage(im_pth.c_str(), CV_LOAD_IMAGE_COLOR);

int iImgChnl = 3;

int iImgHgt = 227;

int iImgWth = 227;

int num_elem = iImgChnl * iImgHgt * iImgWth;

float* pfImgData;

pfImgData = (float*)malloc(sizeof(float)*num_elem);

float* f_input_data_b = (float*)malloc(sizeof(float)*iImgHgt*iImgWth);

float* f_input_data_g = (float*)malloc(sizeof(float)*iImgHgt*iImgWth);

float* f_input_data_r = (float*)malloc(sizeof(float)*iImgHgt*iImgWth);

for (int i = 0; i < num_elem; i += 3) {

f_input_data_b[i / 3] = (float)(unsigned char)(img->imageData[i]);

f_input_data_g[i / 3] = (float)(unsigned char)(img->imageData[i + 1]);

f_input_data_r[i / 3] = (float)(unsigned char)(img->imageData[i + 2]);

}

for (int i = 0; i < iImgHgt*iImgWth; i++) {

pfImgData[i] = f_input_data_b[i];

}

for (int i = 0; i < iImgHgt*iImgWth; i++) {

pfImgData[i + iImgHgt*iImgWth] = f_input_data_g[i];

}

for (int i = 0; i < iImgHgt*iImgWth; i++) {

pfImgData[i + 2*iImgHgt*iImgWth] = f_input_data_r[i];

}

int ret;

string save_pth = "../cat_227.fread_float.w";

FILE* fout = fopen(save_pth.c_str(), "w");

ret = fwrite((void*)pfImgData, sizeof(float), num_elem, fout);

fclose(fout);

printf("--- pfImgData[5847]=%f, pfImgData[5848]=%f\n", pfImgData[5847], pfImgData[5848]);

//--------------------------------------------------

float* tuopan = (float*)malloc(sizeof(float)*num_elem);

FILE* fin = fopen(save_pth.c_str(), "rb");

ret = fread((void*)tuopan, sizeof(float), num_elem, fin);

fclose(fin);

printf("--- tuopan[5847]=%f, tuopan[5848]=%f\n", tuopan[5847], tuopan[5848]);

printf("--- check here---\n");

return 0;

}

20190309132930081929.jpg

测试环境:VS2013 update5, win32/x64 debug/release模式

调试结果:

20190309132930545796.png

发现第5848个元素是错误的。

通过分别设定字符模式和二进制模式来写入文件,看到了差异:

20190309132930721578.png

第一次出现差异的地方是0x5B60后的一个元素,0x5B60恰好是十进制下的23392,23392=5848 x 4, 4表示sizeof(float)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值