std::string 可以包含嵌入的空值吗?

Posted

技术标签:

【中文标题】std::string 可以包含嵌入的空值吗?【英文标题】:Can a std::string contain embedded nulls? 【发布时间】:2011-02-20 04:57:10 【问题描述】:

对于常规 C 字符串,空字符 '\0' 表示数据结束。

std::string 怎么样,我可以有一个嵌入空字符的字符串吗?

【问题讨论】:

见std::string equivalent for data with NULL characters? 【参考方案1】:

是的,您可以在 std::string 中嵌入空值。

例子:

std::string s;
s.push_back('\0');
s.push_back('a');
assert(s.length() == 2);

注意:std::stringc_str() 成员将始终将空字符附加到返回的字符缓冲区;但是,std::stringdata() 成员可能会也可能不会将空字符附加到返回的字符缓冲区。

小心操作符+=

要注意的一件事是不要在 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::stringdata()c_str() 成员返回 const 指针,因此内存不可修改。使用 &buf.front() 你可以直接修改缓冲区的内容。

【讨论】:

在 C++9x 中,&amp;s.front() 也是可修改的,并保证指向一个连续的缓冲区。虽然在 C++03 中没有这样的保证,但没有任何已知的 C++ 实现在实践中不成立(这也是它如此迅速地添加到 C++0x 的部分原因)。 请注意,从 C++11 开始,.c_str().data 是同义词。特别是,这意味着.data 返回的字符串必须附加一个空终止符。 @PavelMinaev:我认为“C++9x”是“C++0x”的拼写错误(在您发表评论后的一段时间内变成了 C++11)。 s.append("\0world", 6); 优于 s += std::string("\0world", 6);【参考方案2】:

是的。 std::string 只是一个有好处的vector&lt;char&gt;

但是,请小心不要将这种野兽传递给调用.c_str() 并在 0 处停止的东西。

【讨论】:

第一个不是真的,正如我最近了解到的那样。 Vector 的交换保留了迭代器和对内容的引用,字符串不一定。 ***.com/questions/25201758/… @Notinlist:它也有不同的名称!哦,恐怖【参考方案3】:

你可以,但你为什么要这样做?在 std::string 中嵌入 NUL 只是自找麻烦,因为传递 std::string 的函数很可能会使用它的 c_str() 成员,并且大多数人会假设第一个 NUL 表示字符串的结尾。因此,这不是一个好主意。另请注意,在 UTF-8 中,只有 '\0' 会导致 0,因此即使出于 i18n 目的,也没有理由嵌入 NUL。

【讨论】:

感谢您解释为什么这样做。 不,这很愚蠢。 “不要使用std::string 的全部功能,因为您可能c_str() 的结果传递给C 字符串函数而不传递长度”,真的吗?好吧,如果你从不这样做,你会没事的......【参考方案4】:

是的,这是有效的。

字符串中间可以有一个空字符。

但是,如果您使用中间有一个空字符的 std::string 和一个 c 字符串 在未定义的行为小镇中发挥作用 - 没有人愿意在那里!!!:

 int n = strlen( strWithNullInMiddle.c_str() ); // Boom!!!

【讨论】:

strlen 将只返回第一个 null 之前的字符数。这可能是意料之外的行为,但并非未定义。

以上是关于std::string 可以包含嵌入的空值吗?的主要内容,如果未能解决你的问题,请参考以下文章

Azure 流分析 - 您可以查询最新的非空值吗?

sqlite - 忽略 lag/lad 中的空值

pandas 怎么处理表格中的空值

如何检查 var 的空值?

Laravel Eager Loading 删除子项的空值

SQL Server的空值处理策略