C++ std::字符串是否可以包含嵌入的空值?
对于常规C字符串,空字符C++ std::字符串是否可以包含嵌入的空值?,c++,stdstring,c-strings,null-terminated,C++,Stdstring,C Strings,Null Terminated,对于常规C字符串,空字符'\0'表示数据结束 关于std::string,可以给我一个嵌入空字符的字符串吗?是的,这是有效的 在字符串的中间可以有一个空字符。< /P> 但是,如果在中间使用带有C字符串的空字符的STD::string 在一个行为不明确的城市里,你的职能是什么?没有人想去那里!!!: int n = strlen( strWithNullInMiddle.c_str() ); // Boom!!! 是的,您可以在std::string中嵌入空值 例如: std::string
'\0'
表示数据结束
关于std::string
,可以给我一个嵌入空字符的字符串吗?是的,这是有效的
在字符串的中间可以有一个空字符。< /P>
但是,如果在中间使用带有C字符串的空字符的STD::string 在一个行为不明确的城市里,你的职能是什么?没有人想去那里!!!:
int n = strlen( strWithNullInMiddle.c_str() ); // Boom!!!
是的,您可以在
std::string
中嵌入空值
例如:
std::string s;
s.push_back('\0');
s.push_back('a');
assert(s.length() == 2);
注意:std::string
的c_str()
成员将始终向返回的字符缓冲区追加空字符;但是,std::string
的data()
成员可以向返回的字符缓冲区追加空字符,也可以不追加空字符
小心操作员+=
需要注意的一件事是不要在RHS上使用operator+=
和char*
。它只会累加到空字符
例如:
std::string s = "hello";
s += "\0world";
assert(s.length() == 5);
正确的方法是:
std::string s = "hello";
s += std::string("\0world", 6);
assert(s.length() == 11);
存储更常用的二进制数据std::vector
通常,使用std::vector
存储任意二进制数据更为常见
std::vector<char> buf;
buf.resize(1024);
char *p = &buf.front();
std::vector buf;
调整大小(1024);
char*p=&buf.front();
这可能更常见,因为
std::string
的data()
和c_str()
成员返回常量指针,因此内存不可修改。使用&buf.front(),您可以自由地直接修改缓冲区的内容。是。std::string只是一个有好处的向量
但是,要小心将这样的beast传递给调用.c_str()
并在0处停止的对象。可以,但为什么要这样做呢?在std::string中嵌入NUL只是自找麻烦,因为传递std::string的函数很可能使用它的c_str()成员,而且大多数函数都会假设第一个NUL表示字符串的结尾。因此,这不是一个好主意。还请注意,在UTF-8中,只有“\0”将导致0,因此即使出于i18n目的,也没有理由嵌入NUL。请参见strlen
将只返回第一个null之前的字符数。它可能是意外的行为,但不是未定义的。在C++9x&s中,front()
也可以修改,并保证指向连续的缓冲区。虽然C++中没有这样的保证,但是没有已知的C++实现,它在实践中并没有真正的(这部分是为什么它被如此快速地添加到C++ 0x)。注意到C++ 11、<代码>、CXScript()、代码>和<代码>。特别是,这意味着.data
返回的字符串必须附加一个空终止符。@PavelMinaev:我猜想“C++9x”是“C++0x”的一个拼写错误(在你发表评论后不久它就变成了C++11)。s.append(“\0world”,6)
优于s+=std::string(“\0world”,6)正如我最近了解到的,第一个不是真的。Vector的交换保留了迭代器和对内容的引用,而字符串则不一定@它也有一个不同的名字!哦,恐怖,谢谢你解释为什么不做。不,这很愚蠢。“不要使用std::string
的全部功能,因为您可能会将c_str()
的结果传递给c-string函数,而不传递长度”,真的吗?好吧,如果你不这样做,你会没事的。。。