为什么C++fstream在循环中调用std::getline后需要调用clear()



在下面的代码中,我从一个只包含";12345";使用std::getline,并在尝试写入";67890〃;到文件。除非我第一次调用myfile.clear((,否则这个写操作将失败。为什么会这样?到底什么东西坏了?有没有一种方法可以在循环中仍然使用std::getline,但防止在读取最后一行时发生错误?什么是正确的?

#include <fstream>
#include <iostream>
#include <string>
using std::cout;
using std::fstream;
using std::string;
void printStats(fstream&);
int main(int argc, char* argv[])
{
// textfile.txt:
// 1234 
fstream myfile("textfile.txt", std::fstream::in | std::fstream::out);
string line;

cout << "n"
<< "Before reading lines in a loop.n";
printStats(myfile);

cout << "n" 
<< "Reading lines in the loop.n";
while (myfile.eof() != true)
{   
std::getline(myfile, line);     // Last call here causes EOF and FAIL bit to be set
cout << "line=" << line << "n";
}

cout << "n" 
<< "After reading lines in a loop.n";
printStats(myfile);

myfile.clear(); // If I comment this out the write below fails

myfile << "67890n";

myfile.close();

return 0;
}
void printStats(fstream& fileStream)
{
int position = fileStream.tellp();
cout << "position = " << position << "n";
if (fileStream.eof() == true)
cout << "EOF bit  = 1n";
else
cout << "EOF bit  = 0n";
if (fileStream.fail() == true)
cout << "FAIL bit = 1n";
else
cout << "FAIL bit = 0n";
if (fileStream.bad() == true)
cout << "BAD bit  = 1n";
else
cout << "BAD bit  = 0n";
}

以下是用myfile.clear((注释掉的执行结果:

user@Ubuntu:~/example/test$ cat textfile.txt ; ./test ; cat textfile.txt 
12345
Before reading lines in a loop.
position = 0
EOF bit  = 0
FAIL bit = 0
BAD bit  = 0
Reading lines in the loop.
line=12345
line=
After reading lines in a loop.
position = -1
EOF bit  = 1
FAIL bit = 1
BAD bit  = 0
12345

以下是使用代码中包含的myfile.clear((执行的结果:

user@Ubuntu:~/example/test$ cat textfile.txt ; ./test ; cat textfile.txt 
12345
Before reading lines in a loop.
position = 0
EOF bit  = 0
FAIL bit = 0
BAD bit  = 0
Reading lines in the loop.
line=12345
line=
After reading lines in a loop.
position = -1
EOF bit  = 1
FAIL bit = 1
BAD bit  = 0
12345
67890

这是在Ubuntu Linux 20.04 上用g++编译的

user@Ubuntu:~/example/test$ /usr/bin/g++ --version
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我确实在下面找到了类似的结果,但它并没有清楚地解释我问题的答案。

在带有读入int数组的文件中使用时,c++getline((是否循环?

看起来您遇到了while(!in.eof())通常错误的原因问题。eofbit直到您尝试读取文件末尾之后才会设置,因为您使用getline进行读取,所以也会设置failbit。然后,当myfile.fail()为真时,流拒绝写入,直到您清除它。

最新更新