【问题标题】:fopen doesn't open file completelyfopen 没有完全打开文件
【发布时间】:2012-09-04 20:16:26
【问题描述】:

我正在编写一个程序,该程序从两个单独文件中的两个表创建一个查找表。当我阅读第一张表格时,一切都被正确阅读。但是,当我阅读第二个文件时,fopen 似乎并没有打开整个文件。

我这样说是因为编译器实现了_iobuf 文件结构,并且_cnt 的初始化似乎比第一次初始化时低很多(_cnt = 530),正如我从文件它减少。

这是我的代码的 sn-p:

int vertical,horizontal,channels,count;
FILE *fp;

fp = fopen(filename,"r");
if(fp==NULL){
    cout << "File not found" << endl;
    return Mat();
}else{
    cout << "Opening and Reading " << filename << endl;
}

//Read header
fread(&count,4,1,fp);
cout << "ReadHistogram(): Count number is " << count;
if(count!= 5){
    cout << "Header file reads: " << count << endl;
    return Mat();
} 

//Read size
fread(&vertical,4,1,fp);
//cout << "ReadHistogram(): Vertical size:" << vertical <<endl;

fread(&horizontal,4,1,fp);
//cout << "ReadHistogram(): Horizontal size:" << horizontal <<endl;

fread(&channels,4,1,fp);
//cout << "ReadHistogram(): Channel size:" << channels<<endl;

//Create Mat array
int size[] = {vertical, horizontal, channels};
Mat histogram(3,size,CV_64F,Scalar::all(0));

//Read in array
count = 0;
for(int i=0;i<vertical;i++){
    for(int j=0;j<horizontal;j++){
        for(int k=0;k<channels;k++){
            double temp5;
            fread(&temp5,8,1,fp);
            histogram.at<double>(i,j,k) = temp5;
            if(count <= 300){
                cout << "Array(" << i+1 << "," << j+1 << "," << k+1 << ")" << "=" << histogram.at<double>(i,j,k) << endl;
                cout << "Temp5 is " << temp5 << endl;
            }
            count++;
        }
    }
}
cout << "Done reading " << filename << endl;
fclose(fp);
return histogram;

PS:我一直试图在FILE 结构中查找_cnt 到底是什么,但我找不到任何类似的东西。任何人都可以提供任何指示,我将不胜感激。

【问题讨论】:

  • 你能读取文件的全部内容吗?
  • 是的,我可以读取值,但只有 for 循环开头的值是正确的。问题在于,在某一点之后,fread 开始返回与文件中不同的值。
  • 如果先读取第二个文件会发生什么?两次之间发生了什么变化?是否涉及任何线程?您是否同时在其他任何地方使用该文件?尝试使您的功能更短。请发帖SSCCE
  • FILE 结构的成员是私有的。不要担心它们是否具有您期望的值。如果对文件定义的操作(fopenfreadfclose 等)行为不正确,那么你有一个合法的问题。

标签: c++ file file-io file-structure


【解决方案1】:

看起来您正在以文本模式读取二进制文件。尝试将“b”添加到 fopen 中的标志:

fp = fopen(filename, "rb");

还要检查 fread 的返回值,如果它比你预期的少,检查 ferror 代码。

【讨论】:

  • +1,当文件以文本模式打开时,字节0x1A被识别为文件结束标记。
  • 啊!! KK 非常感谢!! :)
【解决方案2】:

您的代码看起来不错,但您应该检查fread 的返回值。如果您正在研究 FILE 的内部结构,您只是在寻求混淆。 _cnt 可能与在内存中缓冲了多少文件有关。它不是 API 的一部分,因此没有记录在案,您不应该查看它。

到底是什么问题? fread 什么时候失败,返回什么?

【讨论】:

  • 当我开始读取文件时, fread 返回的所有值都是正确的。但是,在某个点之后, fread 开始一遍又一遍地返回相同的值。我提到 _cnt 的唯一原因是当 _cnt = 0 时 fread 开始一遍又一遍地读取相同的值。
  • 导致我出现问题的 fread 是嵌套 for 循环中的那个。
  • 对不起。我说 fread 返回的所有值都是正确的。这仅适用于前几个值。但在某一点之后,它开始一遍又一遍地返回相同的值。
  • @RommelAlonzo:我的意思是fread 的返回值——不是temp5 返回的值,而是fread 返回的整数,它告诉你它读取了多少元素。当它返回 0 时,使用ferrorfeof 找出发生了什么。
  • 忍受别人所说的话,为了理智,帮自己一个忙。分配整个文件大小的缓冲区,然后一次性读取整个文件。调试它,看看内容是否正确然后。有些东西告诉我我们遗漏了一些东西。哦,检查fread的返回结果=)
【解决方案3】:

是的,我可以读取值并且它们是正确的。问题是,在某个点之后,fread 开始返回相同的值。

我打算在这里给出一个答案,而不是继续讨论;如果我不在基地,我会删除。

我预计发生的情况是您已经阅读了文件的全部内容,但是您并没有停止阅读;随后对 fread() 的调用将返回一个错误(您没有检查它)并且没有修改您的读取缓冲区的内容。

要么检查 fread() 的返回,要么调用 feof() 来检查您的状态,或两者兼而有之。

【讨论】:

  • 我同意,但问题是实际文件包含的值比程序正在读取的值多。我有两个与我正在阅读的大小完全相同的文件。当我阅读整个第一个文件时,一切都被正确读取。当我阅读第二个文件时,问题就来了。两个文件大小相同。
  • 相同大小,在这种情况下,并不重要,因为您的程序认为大小是基于内容的;如果这些内容有误(并且表明数据比实际数据多,基于verticalhorizontalchannels),那么您的程序将继续调用 fread()。
  • 好吧,我在 matlab 程序中使用相同的文件,但 matlab 正确读取所有值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
相关资源
最近更新 更多