C++中两种字符串操作案例的差异及直接赋值单个字符后无法输出完整字符串的问题
为什么直接给空std::string的索引赋值后,无法输出完整字符串?
这是个非常典型的std::string初学者踩坑点,咱们先把两种操作的核心差异说清楚:
两种操作的本质区别
第一种场景(空字符串直接赋值索引):
你用string abc;创建的是一个空字符串,它的size()和length()都是0,内部并没有为字符分配可修改的有效存储空间(仅指向一个不可修改的空终止符)。
当你执行abc[0] = 'm';时,这属于越界访问,是C++标准定义的未定义行为——有些编译器可能会让你侥幸读取到这个字符(比如cout << abc[0]能输出'm'),但字符串本身的size()还是0,所以直接输出整个abc时,因为长度为0,自然什么都不会显示。第二种场景(赋值字符串字面量):
xyz = "village";是std::string的合法赋值操作,它会自动完成三个关键步骤:- 分配足够的存储空间容纳"village"的所有字符(包括末尾的空终止符)
- 把字面量内容复制到字符串内部
- 更新字符串的
size()为7("village"的字符数)
所以不管输出整个字符串还是单个索引的字符,都能得到预期结果。
正确的做法:如何给空字符串设置第一个字符
如果你想创建一个以'm'开头的字符串,要用合法的方式初始化或修改,比如:
// 方式1:直接初始化单个字符的字符串 string abc(1, 'm'); // 方式2:先添加字符 string abc; abc.push_back('m'); // 方式3:直接赋值字符串字面量 string abc; abc = "m";
用这些方式后,abc的size()会被正确设置为1,输出整个字符串就能看到'm'了。
补充:关于std::string的operator[]
要注意,std::string的operator[]只有在索引值小于size()时才合法(可读写);当索引等于size()时,只能读取(返回空终止符的引用,不能修改)。空字符串的size()是0,所以abc[0]的访问本身就不合法,结果完全依赖编译器实现,这也是你能读到'm'但输出整个字符串为空的原因。
内容的提问来源于stack exchange,提问作者Aditya Vaste
相关产品推荐
相关产品推荐

