2009-09-29 129 views
3

我有一个存储在文本文件中的n×2矩阵。我尝试用C读取它++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());  

} 

第一断言失败,系统即fin.fail()为真,当nb_try == N,当它试图读取不存在所述第一数量恰好。但是,在阅读最后一个数字后,fin.eof()怎么不是真的?这是否意味着只有在读取不存在的第一个数字时才会变为真? fin.fail()和fin.eof()在同一时间也变成了真的吗?

感谢和问候!

回答

13

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

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

标准模式是:

while(getlineOrValues) 
{ 
    // Do Stuff 
} 

所以看你的代码,很快我认为这将是asier将它写为:

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是真实的。所以你阅读最后一行并得到值,并且没有什么可读的,但EOF仍然是错误的,所以代码重新进入循环。当它尝试并读取c_tmp时,EOF被触发并且您的断言变成梨状。

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

+0

谢谢!当fin.eof()完全正确时?读完文件中的最后一个数字后,或者在尝试读取不存在的第一个数字之后? fin.fail()的同样问题? – Tim 2009-09-29 19:16:47

+2

当您尝试并阅读__past__ EOF时,EOF为true。读到文件末尾不会改变状态。因此,当您读取文件末尾不存在的第一个值时,EOF会变为真。 – 2009-09-29 19:18:49

+0

再次感谢!这澄清了EOF。对于ifstream :: fail(),如果第一次读取文件的末尾,就像eof()一样,它是否成为真?在我的例子中,这似乎是真的。但是我从http://www.cplusplus.com/reference/iostream/ios/fail/了解到,“如果failbit或badbit被设置,函数返回true,至少有一个标志在其他错误时被设置比在输入操作期间发生的文件结束“。它是否说失败()不会因为EOF发生而变为真? – Tim 2009-09-29 20:54:40

4

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

+0

谢谢!这有帮助! – Tim 2009-09-29 20:55:33

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()为true,但eof()为false,则文件存在问题。

+0

我尝试了第一种情况,并且“#4将返回true”是不正确的。 – Tim 2009-09-30 01:31:15