Tom*_*ert 6 c++ string cout vector
在下面的C++代码中,我意识到gcount()
返回的数字比我想要的更多,因为它getline()
消耗了最终的换行符,但是没有将它发送到输入流.
但我仍然不明白的是程序的输出.对于输入"Test \n",为什么我得到"est \n"?为什么我的错误会影响字符串的第一个字符,而不是在末尾添加不需要的垃圾?为什么程序的输出与字符串在调试器中的显示方式不一致("Test \n",正如我所期望的那样)?
#include <fstream>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
const int bufferSize = 1024;
ifstream input( "test.txt", ios::in | ios::binary );
vector<char> vecBuffer( bufferSize );
input.getline( &vecBuffer[0], bufferSize );
string strResult( vecBuffer.begin(), vecBuffer.begin() + input.gcount() );
cout << strResult << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Ais*_*ina 12
我也复制了这个结果,Windows Vista,Visual Studio 2005 SP2.
当我弄清楚到底发生了什么时,我会更新这篇文章.
编辑:好的,我们去吧.问题(以及人们得到的不同结果)来自\ r \n.如果您调用input.getline
并将结果放入vecBuffer,会发生什么.getline函数剥离\n,但将\ r留在原位.
然后将vecBuffer转换为字符串变量,但是使用输入中的gcount函数,这意味着你将得到一个char太多,因为输入变量仍包含\n,而vecBuffer不包含.
由此产生的strResult是:
- strResult "Test"
[0] 84 'T' char
[1] 101 'e' char
[2] 115 's' char
[3] 116 't' char
[4] 13 '?' char
[5] 0 char
Run Code Online (Sandbox Code Playgroud)
那么然后打印"Test",然后是回车(将光标放回到行的开头),空字符(覆盖T),最后是\n,它正确地将光标放在新行上.
所以你要么必须删除\ r,要么写一个直接从vecBuffer获取字符串长度的函数,检查空字符.
我在Windows XP Pro Service Pack 2系统上复制了Tommy的问题,使用Visual Studio 2005 SP2编译的代码(实际上,它说"版本8.0.50727.879"),作为控制台项目构建.
如果我的test.txt文件只包含"Test"和CR,则程序在运行时会吐出"est"(注意前导空格).
如果我不得不采取疯狂的猜测,我会说这个版本的实现有一个错误,它正在处理Windows换行符,就像它应该在Unix中处理(作为"走到同一行的前面"然后它会清除第一个字符以保存下一个提示的一部分或其他内容.
更新: 玩了一下后,我很肯定这是正在发生的事情.如果你在调试器中查看strResult,你会看到它在末尾复制了十进制13的值.那是CR,在Windows-land中是'\n',其他地方都是"回到行的开头".如果我改为你的构造函数来读取:
string strResult(vecBuffer.begin(),vecBuffer.begin()+ input.gcount() - 1);
...(这样CR不会被复制)然后打印出"测试",就像你期望的那样.
归档时间: |
|
查看次数: |
1832 次 |
最近记录: |