为什么我的字符串末尾多了一个字符?
#include <iostream>
using namespace std;
int main() {
int num;
cin >> num; // Reading input from STDIN
cout << "Input number is " << num << endl; // Writing output to STDOUT
char c1, s2[10];
for (int i=0; i<num; i++)
{
cin >> c1;
if(c1==0){
break;
}
s2[i] = c1;
}
cout <<"output= "<< s2;
}
输出示例
4
Input number is 4
a l e x
output= alex@
为什么“@”被加到字符串的末尾? 起初我以为它是一个随机的垃圾值,但每次我运行程序时,它总是同一个符号
这是因为s2
实际上不是字符串,并且没有\0
字符,这意味着字符串的结尾。 因此,cout
打印您的字符串,并将继续逐个字节地在内存中进一步移动,将每个字符串解释为要输出的字符,直到遇到\0
字符。 为了修复这个问题,您可以用空字符串初始化s2
,这样数组最初将被完全填充\0
。
#include <iostream>
using namespace std;
int main() {
int num;
cin >> num;
cout << "Input number is " << num << endl;
char c1, s2[10] = ""; // Initialize with an empty string
for (int i = 0; i < num; i++)
{
cin >> c1;
if (c1 == 0) {
break;
}
s2[i] = c1;
}
cout << "output= " << s2;
}
cout
,当打印C字符串时,期望它以零终止。 而对于数组s2
还没有这样做。
您可以将整个数组初始化为零:
char s2[10] = {};
或者仅以零终止最后一个字节:
for (int i=0; i<num; i++)
{
cin >> c1;
if(c1==0) {
break;
}
s2[i] = c1;
}
s2[num] = '\0';
在任何情况下,您都需要警惕潜在的缓冲区溢出(例如,如果num
太大)。
或者,您可以考虑使用std::string
来代替固定长度的数组。
您正在读取一个尚未初始化的内存位置。 通过使用一个十个字符的数组,并且只初始化前四个字符(或者其他任何数字),所有其他字符都保持未初始化状态。 从一个未初始化的位置实际读取什么数据是未定义的,这意味着它很大程度上取决于您的编译器选择从该位置读取“@”的等价值。 您可以通过使用适当大小的内存位来修复该问题。 为此,您只需替换一行
char c1, s2[10];
与
char c1;
char* c2 = new char[num]
通过这种方式,您可以动态地精确分配所需的大小。