C++ 中的文件结束

问题描述 投票:0回答:3

我有一个 n X 2 矩阵,按原样存储在文本文件中。我尝试用 C++ 阅读它

nb_try=0;
fin>>c_tmp>>gamma_tmp;
while (!fin.eof( ))      //if not at end of file, continue reading numbers
{
  // store
  cs_bit.push_back(c_tmp);
  gammas_bit.push_back(gamma_tmp);
  nb_try++;

  // read
  fin>>c_tmp;
  assert(!fin.fail( )); // fail at the nb_try=n   
  if(fin.eof( ))break;
  fin>>gamma_tmp; // get first number from the file (priming the input statement)
  assert(!fin.fail( ));    

}

当 nb_try==n 时,第一个断言失败,即 fin.fail( ) 为 true,当它尝试读取第一个不存在的数字时会发生这种情况。但为什么 fin.eof( ) 在读取最后一个数字后不为 true 呢?这是否意味着只有在读取第一个不存在的数字时它才成立? fin.fail( ) 和 fin.eof( ) 同时变为 true 是真的吗?

感谢和问候!

c++ eof
3个回答
18
投票

这是读取文件的错误方法:

while (!fin.eof( ))
{
      // readLine;
      // Do Stuff
}

标准图案是:

while(getlineOrValues)
{
    // Do Stuff
}

所以快速查看你的代码,我认为将其写为更容易:

while(fin>>c_tmp>>gamma_tmp)
{
    // loop only entered if both c_tmp AND gamma_tmp
    // can be retrieved from the file.

    cs_bit.push_back(c_tmp);
    gammas_bit.push_back(gamma_tmp);
    nb_try++;   
} 

问题是 EOF 仅在您尝试阅读过去之后才为真。文件中没有剩余字符可供读取与 EOF 为 true 不同。因此,您读取了最后一行并获取了值,并且没有任何内容可读取,但 EOF 仍然为 false,因此代码重新进入循环。当它尝试读取 c_tmp 时,EOF 就会被触发,你的断言就会变成梨形。

解决办法就是把read作为while条件。读取的结果是流。但是,当在布尔上下文(例如 while 条件)中使用流时,它会转换为可以像 bool 一样使用的类型(从技术上讲,它是 void*,但这并不重要)。


5
投票

IIRC,直到您实际尝试读取文件末尾之后,eofbit 才会被设置。也就是说,一旦到达文件末尾,您必须再读一次才能设置该标志。


0
投票

如果文本文件包含此序列(不带引号)“12345 67890”,则 #3 将返回 false,但 #4 将返回 true,因为最后一个数字后面没有空格:

int i;
bool b;

fin >> i;

b = fin.fail();  // 1
b = fin.eof();   // 2

fin >> i;

b = fin.fail();  // 3
b = fin.eof();   // 4

fin >> i;

b = fin.fail();  // 5
b = fin.eof();   // 6

但是,如果序列是“12345 6789”(注意最后一个数字后面的空格),那么#3和#4都将返回false,但#5和#6将返回true。

您应该检查eof() 和fail(),如果两者都为真,则没有更多数据。如果fail()为真,但eof()为假,则文件有问题。

© www.soinside.com 2019 - 2024. All rights reserved.