我有一个 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 是真的吗?
感谢和问候!
这是读取文件的错误方法:
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*,但这并不重要)。
IIRC,直到您实际尝试读取文件末尾之后,eofbit 才会被设置。也就是说,一旦到达文件末尾,您必须再读一次才能设置该标志。
如果文本文件包含此序列(不带引号)“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()为假,则文件有问题。