相关问题来源于《C++ Primer》第五版中678页的代码
#include <iostream>
using std::cerr; using std::endl;
#include <fstream>
using std::fstream;
#include <string>
using std::string;
#include <cstdlib> // for EXIT_FAILURE
int main()
{
// open for input and output and preposition file pointers to end-of-file
// file mode argument
fstream inOut("D:\\文字相关\\test.txt",
fstream::ate | fstream::in | fstream::out);
if (!inOut) {
cerr << "Unable to open file!" << endl;
return EXIT_FAILURE; // EXIT_FAILURE
}
// inOut is opened in ate mode, so it starts out positioned at the end
auto end_mark = inOut.tellg();// remember original end-of-file position
inOut.seekg(0, fstream::beg); // reposition to the start of the file
size_t cnt = 0; // accumulator for the byte count
string line; // hold each line of input
// while we haven't hit an error and are still reading the original data
while (inOut && inOut.tellg() != end_mark
&& getline(inOut, line)) { // and can get another line of input
cnt += line.size() + 1; // add 1 to account for the newline
auto mark = inOut.tellg(); // remember the read position
inOut.seekp(0, fstream::end); // set the write marker to the end
inOut << cnt; // write the accumulated length
// print a separator if this is not the last line
if (mark != end_mark) inOut << " ";
inOut.seekg(mark); // restore the read position
}
inOut.seekp(0, fstream::end); // seek to the end
inOut << "\n"; // write a newline at end-of-file
return 0;
}
当读取给定给定的文件时,我的运行结果与答案不符,搞了一晚上也没弄懂哪里的问题。
正常应该读取的和生成文件内容如下:
但是我的运行结果却始终是
研究了一晚上了,没搞明白问题在哪里。后来我就通过getline试验是不是文件位置的问题。比如我通过如下代码:
streampos mark1 = inOut.tellg();
getline(inOut, line);
streampos mark2 = inOut.tellg();
cout << "end_mark: " << end_mark << endl;
cout << "mark1: " << mark1 << endl;
cout << "mark2: " << mark2 << endl;
输出结果如下:
这里可以很明显的看到,第一次由于我们先前调用的inOut.seekg(0, fstream::beg);起始位置在0是正确的,可是仅用了一次getline,位置却定位在了8,这是为什么!?读取了一行过后,不应该是定位在5吗?定位在8就像是读了两行一样。这到底是为什么啊。
问题总结如下:
1.为什么一个回车要占位2个?(我这里一共10个字母再加上3个回车,显示的end_mark是16.)
2.为什么getline()在这里失效?是代码哪里出了问题吗?(我用的是官网的代码啊)
3.能告诉我该怎么修改代码才能正确运行吗?