我在 C++ 中遇到了字符串和空字符的问题。空字符的行为与预期不同。

3
我遇到了一个关于C++字符串和空字符的问题。 当我在字符串中间写入'\0'并打印该字符串时,我只能得到'\0'之前的部分,但是当我将字符串作为输入并更改任何索引为'\0'时,它的打印结果会不同。为什么会这样?而且为什么在两种情况下sizeof(string)都是32? 参考代码如下,请帮忙解答。
第一个代码:
#include<iostream>
using namespace std;
int main(){
string s = "he\0llo";

cout<<s.length()<<"\n";
cout<<s<<endl;
cout<<sizeof(s)<<"\n";
}

第一个代码的输出:

2\n
he\n
32\n

第二段代码

#include<iostream>
using namespace std;
int main(){
string s;
cin>>s;
s[1] = '\0';
cout<<s<<"\n";
cout<<s.length()<<"\n";
cout<<sizeof(s)<<"\n";
return 0;
}

第二段代码的输出:
hllo\n
5\n
32\n

以下是供您参考的图片。 这里输入图片描述

3
sizeof(s) 表示的是 std::string 对象本身的大小,与实际字符串中的数据量无关。请注意不要改变原文意思。 - Retired Ninja
string s = "he\0llo"; 改为 auto hello = "he\0llo"; string s(hello, hello + sizeof hello - 1); - Eljay
2个回答

4

std::string的隐式const CharT*构造函数和赋值运算符不知道字符串参数的确切长度。相反,它只知道这是一个const char*,被迫假设该字符串将是null-terminated,因此使用std::char_traits::length(...)(实际上是std::strlen)计算长度。

因此,使用以下表达式构造std::string对象:

std::string s = "he\0llo";

会将字符串的长度计算为2,因为它假定第一个\0字符是该字符串的空终止符,而你的第二个示例是:

s[1] = '\0';

只是在已构建的字符串中简单地添加一个空字符——这不会改变字符串的大小。
如果您想在字符串中间构造一个带有空字符的字符串,就不能让它自己计算字符串的长度。相反,您需要以其他方式构造std::string并为其提供长度。可以使用string(const char*, size_t)构造函数或迭代器对来完成这一点,如果这是一个数组的话。
// Specify the length manually
std::string s{"he\0llo",6};

实时示例

// Using iterators to a different container (such as an array)
const char c_str[] = "he\0llo";
std::string s{std::begin(c_str), std::end(c_str)};

现场示例

注意: sizeof(s) 是告诉您标准库实现中 std::string 类本身的字节数。这并不告诉您所包含的字符串长度 - 这可以通过 s.length()s.size() 来确定。


3

从c++14开始,可以使用std::literals将带引号的字符串指定为std::string的选项。这可以防止将一个字符数组转换为字符串,因为它会自动停在第一个空字符处。

#include<iostream>
#include <string>
using namespace std;
using namespace std::literals;

int main() {
    string s = "he\0llo"s;   // This initializes s to the full 6 char sequence.
    cout << s.length() << "\n";
    cout << s << endl;
    cout << sizeof(s) << "\n";  // prints size of the s object, not the size of its contents
}

结果:

6
hello
28

哦,我从没想过字符串字面运算符可以用于这个目的。好答案! - Human-Compiler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接