提问者:小点点

正在向字符串中添加额外字符


为什么我的字符串末尾多了一个字符?

#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@ 

为什么“@”被加到字符串的末尾? 起初我以为它是一个随机的垃圾值,但每次我运行程序时,它总是同一个符号


共3个答案

匿名用户

这是因为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]

通过这种方式,您可以动态地精确分配所需的大小。