C++流 get unget 不是 nop 吗?
我有以下 C++ 程序,并在 Windows 7 上使用 Visual Studio 2008 运行它。我获取然后取消获取一个字符。这样做之后,文件位置就不同了。为什么?我该如何解决这个问题?
test.txt(如果需要,请下载以下链接)
/* Comment 1 */
/* Comment 2 */
#include <fstream>
int main (int argc, char ** argv) {
char const * file = "test.txt";
std::fstream fs(file, std::ios::in);
std::streampos const before = fs.tellg();
// replacing the following two lines with
// char c = fs.peek(); results in the same problem
char const c = fs.get();
fs.unget();
std::streampos const after = fs.tellg();
fs.seekg(after);
char const c2 = fs.get();
fs.close();
return 0;
}
c: 47 '/' char
c2: -1 'ÿ' char
之前:{_Myoff=0 _Fpos =0 _Mystate=0 } std::fpos
- 之后:{_Myoff=0 _Fpos=-3 _Mystate=0 } std::fpos
添加 | std::fstream::binary
到构造函数似乎可以解决问题。也许它与文件中的换行符有关?如果是这样,为什么它会影响甚至无法读取换行符的代码?
更新为寻找后位置并获得另一个角色。
看来通过记事本保存与通过 Vim 保存有区别。通过记事本保存使流正常工作。
我已将文件上传到 Google 文档,如果您想下载它:
I have the following C++ program and ran it using Visual Studio 2008 on Windows 7. I get and then unget a character. After doing so, the file position is different. Why? How do I get around this problem?
test.txt (download link below if you want)
/* Comment 1 */
/* Comment 2 */
#include <fstream>
int main (int argc, char ** argv) {
char const * file = "test.txt";
std::fstream fs(file, std::ios::in);
std::streampos const before = fs.tellg();
// replacing the following two lines with
// char c = fs.peek(); results in the same problem
char const c = fs.get();
fs.unget();
std::streampos const after = fs.tellg();
fs.seekg(after);
char const c2 = fs.get();
fs.close();
return 0;
}
c: 47 '/' char
c2: -1 'ÿ' char
before: {_Myoff=0 _Fpos=0 _Mystate=0 } std::fpos<int>
after: {_Myoff=0 _Fpos=-3 _Mystate=0 } std::fpos<int>
Adding | std::fstream::binary
to the constructor seems to solve the problem. Perhaps it has to do with newlines in the file? If so, why does it affect code that doesn't even get close to reading a newline?
Updated with a seeking to the after position and getting another character.
It seems that saving via Notepad vs. Vim makes a difference. Saving via Notepad makes the stream work okay.
I have uploaded the file to google docs if you want to dl it:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好的,使用您的输入文件,我看到了与您相同的行为。经过一些实验,看起来该文件是 Unix 格式,然后编辑了 ^M 字符(至少这就是我能够重现它的方式)。
为了解决这个问题,我在 Vim 中编辑了文件,执行“:set ff=dos”,然后添加和删除了一个字符来弄脏文件,然后保存它。
Ok using your input file I see the same behavior you do. After some experimentation, it looks like the file was in Unix format, then had the ^M characters edited out (at least that's how I was able to reproduce it).
To fix it, I edited the file in Vim, executed ":set ff=dos", then added and deleted a character to dirty the file, then saved it.
文件位置的行为符合预期:
构建并运行:
或者,我不明白问题出在哪里。
The file position behaves as expected:
Build and run:
Or, I don't understand where is the problem.