C++:关于空字符

car*_*031 11 c++ operators stdstring null-character double-quotes

有两个string变量,mn:

#include <string>

string m = "0100700\0"
cout << m.size() << endl; // it prints: 7

string n;
n += "0100700"
n += '\0';
cout << n.size() << endl; // it prints: 8
Run Code Online (Sandbox Code Playgroud)

我猜两个都有8个字符,但m只有7个字符,n有8个字符.为什么会这样?

jua*_*nza 10

首先要注意的是,std::string没有一个构造函数可以从底层数组推断字符串文字的长度.它有一个构造函数接受a const char*并将其视为以null结尾的字符串.在这样做时,它会复制字符,直到找到第一个字符\0.

这是使用的构造函数string m = "0100700\0";,这就是为什么在第一种情况下你的字符串长度为7.注意,没有其他方法可以从指向第一个元素的指针获取char数组的长度.

在第二个示例中,您将一个字符添加到std::string长度为7 的预先存在的对象中.这会将长度增加到8.如果要迭代字符串的元素,您将能够看到第8个元素是'\0'.

for (auto c: n)
    if (c == 0) std::cout << "null terminator" << std::endl;
Run Code Online (Sandbox Code Playgroud)

要初始化包含'\0'字符的字符串,您有以下选项:

使用初始化列表:

std::string s{'a', 'b', '\0', 'd', 'e', '\0', 'g'};
Run Code Online (Sandbox Code Playgroud)

使用std::string's iterator构造函数从不同的容器或数组构造:

std::vector<char> v{'a', 'b', '\0', 'd', 'e', '\0', 'g'};
char c[] = {'a', 'b', '\0', 'd', 'e', '\0', 'g'};
const char* ps = "ab\0de\0g";

std::string s0(std::begin(v), std::end(v));
std::string s1(std::begin(c), std::end(c));
std::string s2(ps, ps + 8);
Run Code Online (Sandbox Code Playgroud)


πάν*_*ῥεῖ 8

在第1个样本中

 string m = "0100700\0";
Run Code Online (Sandbox Code Playgroud)

string变量是从字符文字构成,采取所有字符,直到达到第一个'\0'发现的字符.

然而,第二个示例显示,您可以'\0'向a 添加任意数量的附加字符std::string并增加其大小.


要回答你的评论中的问题:

要从包含'\0'字符的文字初始化字符串,您可以明确指定计数

string m("0100700\0",8);
Run Code Online (Sandbox Code Playgroud)

或者您可以使用firstlast迭代器使用构造函数:

 const char x[] = "0100700\0";
 string m(std::begin(x),std::end(x));
Run Code Online (Sandbox Code Playgroud)