C语言fread/fwrite填坑记
先说结论用 FILE* fin = fopen("filename","w"); fread(buf,sizeof(char)*num_elem,1,fin); fclose(fin); FILE *fout = fopen("filename","r"); fwrite(buf,fout); fclose(fout); 如果是要写入非字符的数据,例如float数组、int数组等,则一定要用二进制模式打开文件( FILE* fin = fopen("filename","wb"); fread(buf,sizeof(float)*num_elem,"rb"); fwrite(buf,fout); fclose(fout); 原因:字符模式打开的文件,在windows下,遇到0x0D和0x0A(分别是 举例细说读取图像,通常用opencv,但是考虑到arm上用opencv过于庞大,考虑在pc上把图像的数据读取出来,然后整理下顺序,再用fwrite保存。后面在arm上直接fread就行了,避开了opencv。 但在具体实现的时候发现,fwrite后再fread,只有前面一部分数据是正确的!原因如上面说的,保存到文件的是float数组,但是打开文件的模式错误的设定为了字符模式,而不是二进制模式。 #include <stdio.h> #include <stdlib.h> #include <iostream> #include <string> #include <vector> #include <opencv2/opencv.hpp> 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]=%fn",pfImgData[5847],pfImgData[5848]); //-------------------------------------------------- float* tuopan = (float*)malloc(sizeof(float)*num_elem); FILE* fin = fopen(save_pth.c_str(),"rb"); ret = fread((void*)tuopan,fin); fclose(fin); printf("--- tuopan[5847]=%f,tuopan[5848]=%fn",tuopan[5847],tuopan[5848]); printf("--- check here---n"); return 0; } 测试环境:VS2013 update5,win32/x64 debug/release模式 调试结果: 发现第5848个元素是错误的。 通过分别设定字符模式和二进制模式来写入文件,看到了差异: 第一次出现差异的地方是0x5B60后的一个元素,0x5B60恰好是十进制下的23392,23392=5848 x 4,4表示sizeof(float) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |