3

我有一个 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() 为真,这发生在它尝试读取第一个不存在的数字时。但是为什么 fin.eof( ) 在读完最后一个数字后不是真的呢?这是否意味着只有在读取第一个不存在的数字时它才成为真的?fin.fail( ) 和 fin.eof( ) 是否同时成为真的?

谢谢并恭祝安康!

4

3 回答 3

16

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

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

标准模式是:

while(getlineOrValues)
{
    // Do Stuff
}

因此,快速查看您的代码,我认为将其编写为:

while(fin>>c_tmp>>gamma_tmp)
{
    // loop only eneterd 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 仍然是错误的,因此代码重新进入了循环。当它尝试读取 c_tmp 时,EOF 被触发并且你的断言变成梨形。

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

于 2009-09-29T19:09:02.433 回答
5

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

于 2009-09-29T19:16:02.623 回答
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() 为假,则文件存在问题。

于 2009-09-30T00:04:58.420 回答