【问题标题】:C++: How do null characters work in std::string?C++:空字符如何在 std::string 中工作?
【发布时间】:2017-03-07 16:41:25
【问题描述】:

我来自 C 背景,在学习 C++ 时遇到了<string> 头文件。在 C 中,字符串是一个以'\0' 结尾的字符数组。

但是,在std::string 中,我发现情况并非如此,并且在任何有效索引处插入/替换 null 字符时不会像我预期的那样修剪字符串。

string s;

getline(cin, s);

// remove all punctuation 
for(string::size_type i = 0, n = s.size(); i < n; i++)
{
     if(ispunct(s[i]))
         s[i] = '\0';
}

输入:你好,世界!!!!

输出:Hello World

预期输出:你好

在观察上述行为时,我假设 C++ 中的字符串不是以空值结尾的。然后我在 SO Use of null character in strings (C++) 上发现了这个问题,这让我很困惑。

string s = "Hello\0, World";

cout << s << endl;

输出:你好

预期输出:你好,世界

如果有人能解释这种行为背后的原因,将会很有帮助。

【问题讨论】:

  • std::string 想象成一个std::vector&lt;char&gt;,它有一个隐藏的额外元素'\0'。这是一个实现细节。获得空终止数组的唯一保证方法是通过std::string::c_str()
  • C++ 中有不止一种字符串。有一种与 C 完全兼容的类型,包括空终止。还有另一种是来自&lt;string&gt; 标头的std::string。第二种字符串不是以空字符结尾的字符数组。

标签: c++ string


【解决方案1】:

std::string 支持嵌入的 NUL 字符*。您的示例代码没有产生预期结果的事实是,因为您正在从指向零终止字符串的指针构造 std::string。没有长度信息,并且 c'tor 在第一个 NUL 字符处停止。 s 包含 Hello,因此是输出。

如果你想构造一个嵌入 NUL 字符的std::string,你必须使用一个带有显式长度参数的c'tor

std::string s("Hello\0, World", 13);
std::cout << s << std::endl;

产生this output:

Hello, World


* std::string 维护一个明确的长度成员,因此它不需要保留一个字符来充当字符串结束标记。

【讨论】:

  • 您必须使用带有显式长度参数的 c'tor...or add the NUL character as an individual element.
  • @zett42:“如果你想构造一个带有嵌入 NUL 字符的std::string。您正在构建一个字符串,然后对其进行修改。那是一个不同的谓词。使用带有显式长度参数、迭代器对或初始化列表的 c'tor 是构造带有嵌入 NUL 字符的 std::string 的唯一方法。
  • 正确。我只是举了另一个例子,如何将 NUL 字符填充到 std::string 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-12
  • 1970-01-01
相关资源
最近更新 更多