2

下面是一个例子来说明这个问题:

// Create/truncate file and save '1'
const string NAME = "example.txt";
fstream file(NAME.c_str(), ios::out | ios::trunc);
file << '1';
file.close();

// Re-open file and output its only line
file.open(NAME.c_str(), ios::in | ios::out | ios::app);
string text;
getline(file, text);
cout << "Read \"" << text << "\"" << endl;
// OUTPUTS: Read "1"

// (Try to) Append '2'
file << '2';
file.seekg(0);
getline(file, text);
cout << "Read \"" << text << "\"" << endl;
// OUTPUTS: Read "1"

// (Try to) Append '3'
file.clear(ios::goodbit); /*** SHOULD IT BE NECESSARY TO CLEAR THIS FLAG? ***/
file << '3';
file.seekg(0);
getline(file, text);
cout << "Read \"" << text << "\"" << endl;
// OUTPUTS: Read "13"

我对包含一行我不太了解的代码感到有些不安!

提前致谢。

4

3 回答 3

2

getline sets the eofbit because it doesn't find the delimiter (newline). So there's certainly a flag set on the stream. ios::goodbit isn't really a bit, it means "all flags clear", so it's the eofbit you're clearing.

I'd be inclined to trust your implementation to respond correctly to that bit when writing, so if it tells you that the write fails then I more or less believe it. Someone will probably do the standards-diving to find the relevant text.

Why does not seekg(0) clear the eof state of stream? says there's a difference between C++03 and C++11. In C++11, your call to seekg clears the eofbit, so because the write failed you read back "1". In C++03, your call to seekg does not clear the eofbit, so the second read fails and text just happens to still contain "1" from before.

It's almost always incorrect to use << or >> without checking the state of the stream immediately afterwards:

if (file << '2') {
    // seekg and so on to confirm what is in the file
} else {
    std::cout << "write failed" << std::endl;
}
于 2012-12-18T11:22:55.637 回答
1

goodbit isn't a bit you can clear, it's the state of not having any error state flag bits set. In a typical implementation of ios,

struct ios {
  enum iostate {
    goodbit = 0,
    badbit  = 0x1,
    failbit = 0x2,
    eofbit  = 0x4,
  };
};

The reason that you need to clear the error state flags is that after getline the eofbit is set so the << operator has no effect. You can verify this by printing out the error state:

cout << file.rdstate();
于 2012-12-18T11:22:52.937 回答
0

获取线(文件,文本);

您的文件没有换行符,因此它会读取到文件末尾并设置eofbit

在那之后你不能再读或写,直到你清除eofbit

于 2012-12-18T11:25:55.403 回答