对于普通的C字符串,空字符'\0'
表示数据的结束。
那么对于std::string
类型的字符串,我能否包含空字符呢?
对于普通的C字符串,空字符'\0'
表示数据的结束。
那么对于std::string
类型的字符串,我能否包含空字符呢?
是的,您可以在 std::string
中嵌入空值。
例如:
std::string s;
s.push_back('\0');
s.push_back('a');
assert(s.length() == 2);
注意:std::string
的c_str()
成员函数总是将空字符附加到返回的char缓冲区中;然而,std::string
的data()
成员函数可能会在返回的char缓冲区中附加空字符,也可能不会。
小心使用operator+=
需要注意的一点是不要在RHS上使用char*
与operator+=
。它只会添加到空字符为止。
例如:
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::string
的 data()
和 c_str()
成员函数返回 const 指针,所以内存不可修改,使用 &buf.front() 可以直接修改缓冲区的内容,这种方式更常见。
&s.front()
也是可修改的,并且保证指向一个连续的缓冲区。虽然在C++03中没有这样的保证,但是在实践中没有已知的C++实现不符合这个规定(这也是为什么它很快被添加到C++0x的部分原因)。 - Pavel Minaev.c_str()
和 .data
是同义词。特别是,这意味着由.data
返回的字符串必须附带一个空终止符。 - nneonneos.append("\0world", 6);
is better than s += std::string("\0world", 6);
- n.caillou是的。std::string只是一个带有优势的vector<char>
。
然而,当将这样的“野兽”传递给调用.c_str()
并停在0处的函数时,请小心。
std::string
的全部功能,因为你可能会将c_str()
的结果传递给C字符串函数而没有传递长度”,真的吗?好吧,如果你从来没有这样做过,那么你就没问题了... - Lightness Races in Orbit没错,这是有效的。
你可以在字符串的中间有一个空字符。
然而,如果你在std::string中使用一个带有空字符的c字符串函数,则会进入未定义的行为区域 - 没有人想去那里!
int n = strlen( strWithNullInMiddle.c_str() ); // Boom!!!
strlen
函数会返回第一个空字符(\0
)之前的字符数。这可能不是预期的行为,但它并非未定义行为。 - Matthew Flaschen