使用字符串文字初始化时 std::strings 是否以 '\0' 结尾?
Do std::strings end in '\0' when initialized with a string literal?
我知道字符串对象不是以 null 结尾的,但为什么要这样做?
std::string S("Hey");
for(int i = 0; S[i] != '[=11=]'; ++i)
std::cout << S[i];
所以构造函数也复制了空终止符,但不增加长度?为什么会麻烦?
So the constructor copies the null terminator as well, but does not increment the length?
如您所知,std::string
不包含空字符(并且它不会在此处复制空字符)。
重点是您正在使用 std::basic_string::operator[]
。根据 C++11,当指定索引等于 size()
.
时,std::basic_string::operator[]
将 return 为空字符
If pos == size()
, a reference to the character with value CharT()
(the null character) is returned.
For the first (non-const) version, the behavior is undefined if this character is modified to any value other than charT()
.
std::string
以空终止 C 字符串的形式在内部存储其数据,但在正常使用中不允许您访问空终止符。
例如,如果我将值 "Hello, World!" 分配给一个字符串,内部缓冲区将如下所示:
std::string myString("Hello, World!");
// Internal Buffer...
// [ H | e | l | l | o | , | | W | o | r | d | ! | [=10=] ]
// ^ Null terminator.
在此示例中,空终止符不是从字符串文字的末尾复制的,而是由 std::string
在内部添加的。
正如@songyuanyao 在他的回答中提到的,结果是 myString[myString.size()];
returns '[=16=]'
.
那么为什么 std::string
会在字符串的末尾分配一个空终止符?它当然不一定要支持一个,因为你可以在一个字符串中添加'[=16=]'
,它包含在字符串中:
std::string myString;
myString.size(); // 0
myString.push_back('[=11=]');
myString.size(); // 1
此行为的原因是为了支持 std::string::c_str()
功能。 c_str()
函数需要 return 空终止 const char *
。最有效的方法是 return 一个指向内部缓冲区的指针,但为了做到这一点 内部缓冲区必须在字符串末尾包含一个空终止符 。自 C++11 起,字符串需要 包含空终止符以支持这一点。
P.S。虽然严格来说不是您问题的一部分,但应该指出,如果您的字符串包含空字符,则您问题的循环可能不是 return 完整字符串:
std::string S("Hey");
S.push_back('[=12=]');
S.append("Jude");
for(int i = 0; S[i] != '[=12=]'; ++i)
std::cout << S[i];
// Only "Hey" is printed!
我知道字符串对象不是以 null 结尾的,但为什么要这样做?
std::string S("Hey");
for(int i = 0; S[i] != '[=11=]'; ++i)
std::cout << S[i];
所以构造函数也复制了空终止符,但不增加长度?为什么会麻烦?
So the constructor copies the null terminator as well, but does not increment the length?
如您所知,std::string
不包含空字符(并且它不会在此处复制空字符)。
重点是您正在使用 std::basic_string::operator[]
。根据 C++11,当指定索引等于 size()
.
std::basic_string::operator[]
将 return 为空字符
If
pos == size()
, a reference to the character with valueCharT()
(the null character) is returned.For the first (non-const) version, the behavior is undefined if this character is modified to any value other than
charT()
.
std::string
以空终止 C 字符串的形式在内部存储其数据,但在正常使用中不允许您访问空终止符。
例如,如果我将值 "Hello, World!" 分配给一个字符串,内部缓冲区将如下所示:
std::string myString("Hello, World!");
// Internal Buffer...
// [ H | e | l | l | o | , | | W | o | r | d | ! | [=10=] ]
// ^ Null terminator.
在此示例中,空终止符不是从字符串文字的末尾复制的,而是由 std::string
在内部添加的。
正如@songyuanyao 在他的回答中提到的,结果是 myString[myString.size()];
returns '[=16=]'
.
那么为什么 std::string
会在字符串的末尾分配一个空终止符?它当然不一定要支持一个,因为你可以在一个字符串中添加'[=16=]'
,它包含在字符串中:
std::string myString;
myString.size(); // 0
myString.push_back('[=11=]');
myString.size(); // 1
此行为的原因是为了支持 std::string::c_str()
功能。 c_str()
函数需要 return 空终止 const char *
。最有效的方法是 return 一个指向内部缓冲区的指针,但为了做到这一点 内部缓冲区必须在字符串末尾包含一个空终止符 。自 C++11 起,字符串需要 包含空终止符以支持这一点。
P.S。虽然严格来说不是您问题的一部分,但应该指出,如果您的字符串包含空字符,则您问题的循环可能不是 return 完整字符串:
std::string S("Hey");
S.push_back('[=12=]');
S.append("Jude");
for(int i = 0; S[i] != '[=12=]'; ++i)
std::cout << S[i];
// Only "Hey" is printed!