C++中字符串转大写后char数组末尾出现垃圾字符的原因是什么?
问题原因与解决方案
嗨,这个问题我太熟悉啦!咱们来搞清楚为啥会出现这些奇怪的垃圾字符~
核心原因:C风格字符串需要终止符
你用cout输出char*类型的时候,它是按照C风格字符串的规则来处理的——会从指针指向的位置开始读取字符,直到碰到'\0'(空字符)才会停止输出。
但你现在的代码里:
str.length()返回的是字符串"asdf"的长度4,所以你只分配了4个字节的内存给str_c- 循环里把4个字符都转成大写存进去了,但没有给
'\0'留位置,也没手动添加这个终止符
这就导致cout输出完"ASDF"后,会继续读取后面的内存(这些内存里的内容是随机的垃圾数据),直到偶然碰到某个'\0'才停下,所以你就看到了那些乱七八糟的字符。
修复方案
只需要做两个小改动:
- 分配内存时多留1个字节的空间给终止符
- 循环结束后手动添加
'\0'
修改后的代码如下:
#include <iostream> #include <string> #include <cctype> // 别忘了包含toupper需要的头文件 using namespace std; int main() { string str{"asdf"}; // 多分配1个字节存终止符 char* str_c = new char[str.length() + 1]; for (int i = 0; i < str.length(); i++) { str_c[i] = toupper(static_cast<unsigned char>(str[i])); // 转成unsigned char是为了避免toupper处理负数的情况(比如某些编码下的字符) } str_c[str.length()] = '\0'; // 手动添加字符串终止符 cout << str_c; // 现在输出就是干净的ASDF啦! delete[] str_c; // 一定要记得释放动态分配的内存,避免内存泄漏 return 0; }
另外补充个小提醒:如果你不需要手动管理内存的话,其实可以直接用string的toupper操作,比如:
string str{"asdf"}; for (char& c : str) { c = toupper(static_cast<unsigned char>(c)); } cout << str;
这样更安全,还不用操心内存和终止符的问题~
内容的提问来源于stack exchange,提问作者ArunJose
相关产品推荐
相关产品推荐

