C++函数中定义的string类型变量s1无法正常打印是什么原因?
C++代码问题解答
s1无法正常打印的核心原因
- 越界访问空字符串,触发未定义行为
你定义的string s1;是默认初始化的空字符串,内部没有分配任何存储字符的空间,长度为0。直接通过s1[j]给对应下标赋值属于非法越界访问,C++标准不会保证该操作的结果,也不会自动给字符串扩容,写入的内容不会被正确识别为s1的有效字符。 - 初始下标错误,首字符被赋值为终止符
你自行计算的字符串长度n是字符串的总字符数,而std::string的合法下标范围是0 ~ n-1,你循环初始值设为i=n,第一次读取的s[i]是字符串末尾隐含的'\0'终止符,赋值给s1[0]后,后续打印整个字符串时碰到'\0'就会判定为字符串结束,所以输出为空。
循环内部打印看起来正常的原因
你说的打印操作放在for循环内部可以成功,本质是你在循环内打印的是刚赋值的单个字符(比如cout << s1[j];),此时虽然越界写入是非法操作,但你写入的s[i]的值刚好被临时读到输出,所以看起来输出正常。如果你在循环内部打印整个s1,仍然会因为首字符是'\0'输出为空。
修正后的参考代码
#include <iostream> #include <string> #include <algorithm> using namespace std; int lengthOfLastWord(string s) { int n = s.size(); string s1; // 先跳过末尾的所有空格 int i = n - 1; while (i >= 0 && s[i] == ' ') { i--; } // 提取最后一个单词的字符 while (i >= 0 && s[i] != ' ') { s1.push_back(s[i]); // 使用push_back自动扩容,避免越界 i--; } // 倒序提取的字符需要反转得到正确的单词 reverse(s1.begin(), s1.end()); cout << s1 << endl; return s1.size(); } int main() { string s; getline(cin, s); lengthOfLastWord(s); return 0; }
内容的提问来源于stack exchange,提问作者ratim shariar
相关产品推荐
相关产品推荐

