![]() |
#2
纯蓝之刃2020-03-18 10:22
|
在上世纪C++98之前,<strstream>中有个std::ostrstream。现在已经被<sstream>中的std::ostringstream给替换了。
std::ostrstream s;
s << "abc";
char* p = s.str(); // 冻结缓冲区(因为返回的是一个指针),并返回 'a','b','c'(注意尾部没有'\0') 这样一个序列的起始地址.
// std::cout << p; 不能这么做,因为 p 不是指向以null结尾的字符串(可以这么做 std::cout.write(s.str(), s.pcount()))
// 正确的做法是解冻后,尾部加个'\0',让它成为以null结尾的字符串
s.freeze(false);
s << ends;
std::cout << s.str(); // 这时是正确的,返回序列 'a','b','c','\0'
s.freeze(false); // 别忘了解冻,否则会内存泄漏
简而言之,std::ostrstream::str() 并不主动在缓冲区添加'\0',所以要想它返回一个null结尾的字符串,用户得自己向缓冲区输出std::ends。s << "abc";
char* p = s.str(); // 冻结缓冲区(因为返回的是一个指针),并返回 'a','b','c'(注意尾部没有'\0') 这样一个序列的起始地址.
// std::cout << p; 不能这么做,因为 p 不是指向以null结尾的字符串(可以这么做 std::cout.write(s.str(), s.pcount()))
// 正确的做法是解冻后,尾部加个'\0',让它成为以null结尾的字符串
s.freeze(false);
s << ends;
std::cout << s.str(); // 这时是正确的,返回序列 'a','b','c','\0'
s.freeze(false); // 别忘了解冻,否则会内存泄漏

#include <iostream>
#include <strstream>
int main()
{
std::ostrstream s; // 动态缓冲区
s << “abc" << std::ends;
std::cout << s.str() << '\n';
s.freeze(false);
}
#include <strstream>
int main()
{
std::ostrstream s; // 动态缓冲区
s << “abc" << std::ends;
std::cout << s.str() << '\n';
s.freeze(false);
}
C++98时新的 std::ostringstream 就没这些破事,不需要冻结缓冲区,也不需要std::ends

#include <sstream>
#include <iostream>
int main()
{
std::ostringstream s;
s << "abc"; // 不需要,也不应该添加 std::ends
std::cout << s.str() << '\n';
// 不需要冻结缓冲区,因为 std::ostringstream::str() 返回的是一个std::string类型的缓冲区副本
}
#include <iostream>
int main()
{
std::ostringstream s;
s << "abc"; // 不需要,也不应该添加 std::ends
std::cout << s.str() << '\n';
// 不需要冻结缓冲区,因为 std::ostringstream::str() 返回的是一个std::string类型的缓冲区副本
}
-------
我又看了一下你们的讨论,似乎不是在纠结 std::ends,而是 一个说putchar('\0')是可以的,一个说putchar('\0')是没意义的。