当读取包含\ 0的stringstream时,C ++ getline()表现得很奇怪

时间:2014-10-03 02:48:11

标签: c++ sockets getline stringstream

我正在尝试从套接字中读取一个大缓冲区,该套接字使用\ 0来分隔数据片段和\ n来分隔行。

我认为getline()是获取每一行的一种简单方法,但它表现得很奇怪。

我正在使用\ n作为getline()中的分隔符。

string line;
string test1 = "aaa,123\nbbb\nccc,456\n";
stringstream ss1(test1);
while(std::getline(ss1, line, '\n')) {
    cout << line << endl;
    }
// outputs:
// aaa,123
// bbb
// ccc,456

string test2 = "aaa\0123\0\nbbb\0\nccc\0456\0\n";
stringstream ss2(test2);
while(std::getline(ss2, line, '\n')) {
    cout << line << endl;
    }
// outputs:
// aaa
// 3

为什么会在test2中发生这种情况? 3来自哪里?我必须删除\ 0才能使其正常工作吗?当我执行socket recv()时,是否有更容易/更好的方法在缓冲区中标记字符串?

2 个答案:

答案 0 :(得分:3)

\0在一个特殊符号中。它显示字符串何时结束。

例如,如果键入"a string",编译器会自动在末尾添加\0,表示字符串结束。但是,在字符串中间放置一个\0是合法的,它只是意味着忽略它之后的所有内容。

基本上,您对字符串执行的任何操作(而不仅仅是getline)都会将字符串视为"aaa",忽略找到的第一个\0之后的所有内容。但...

@Fred Larson指出

  

哦,我知道3来自哪里。第一个\ 0不是null,它是\ 012的开头,它是一个回车符。然后是3。

实际上,该字符串被视为"aaa\n3"。这就是你获得输出的原因。

编辑:感谢Galik,我还要补充一点,我提到的这些规则可能只适用于字符串文字/ c字符串。 std::string s可能是一个不同的情况,其中字符串的长度是提前知道的。

答案 1 :(得分:0)

\ 0是标准的字符串终止符号。因此,您可以逐个字符地读取,或者将\ 0作为delemeters