结束时带有垃圾字符的字符串数组

我有一个char数组缓冲区,我用它来存储用户将逐个输入的字符。 我下面的代码有效,但有一些我无法弄清楚的故障:

  1. 当我执行一个printf来查看Buffer中的内容时,它确实填满了但是我最后得到了垃圾字符
  2. 尽管被声明为char Buffer [8],它不会停留在8个字符;

有人可以向我解释发生了什么,也许我可以解决这个问题? 谢谢。

char Buffer[8]; //holds the byte stream int i=0; if (/* user input event has occurred */) { Buffer[i] = charInput; i++; // Display a response to input printf("Buffer is %s!\n", Buffer); } 

输出:

 tagBuffer是1┬┬w!
 tagBuffer是12┬w!
 tagBuffer是123w!
 tagBuffer是1234!
 tagBuffer是12345!
 tagBuffer是123456 =!
 tagBuffer是1234567!
 tagBuffer是12345678! 

tagBuffer是123456789!

您必须以\ 0字符结束字符串。 这就是为什么它们被称为零终止字符串。

分配1个额外的char来保持\ 0也是明智的。

传递给printf()函数的唯一事情是指向字符串第一个字符的指针。 printf()无法知道数组的大小。 (它甚至不知道它是否是一个实际的数组,因为指针只是一个内存地址。)

printf()和所有标准c字符串函数都假定字符串末尾有一个0。 例如,printf()将在内存中保持打印字符,从传递给函数的char开始,直到它达到0。

因此,您应该将代码更改为以下内容:

 char Buffer[9]; //holds the byte stream int i=0; if( //user input event has occured ) { Buffer[i] = charInput; i++; Buffer[i] = 0; // You can also assign the char '\0' to it to get the same result. // Display a response to input printf("Buffer is %s!\n", Buffer); } 

除了之前关于零终止的注释之外,您还必须承担不溢出自己的缓冲区的责任。 它不会停留在8个字符,因为您的代码没有停止! 你需要类似下面的东西(捎带杰里米的建议):

 #define DATA_LENGTH 8 #define BUFFER_LENGTH (DATA_LENGTH + 1) char Buffer[BUFFER_LENGTH]; //holds the byte stream int charPos=0; //index to next character position to fill while (charPos <= DATA_LENGTH ) { //user input event has occured Buffer[i] = charInput; Buffer[i+1] = '\0'; // Display a response to input printf("Buffer is %s!\n", Buffer); i++; } 

换句话说,确保在达到最大长度时停止接受数据,无论环境试图向您推送什么。

如果您使用C或C ++编程,则必须记住:1)字符串以\ 0字符结束。 2)C在字符串上没有边界检查,它们只是字符数组。

没有人提到这种可能性,这很奇怪:

 char Buffer[8]; //holds the byte stream int i = 0; while (i < sizeof(Buffer) && (charInput = get_the_users_character()) != EOF) { Buffer[i] = charInput; i++; // Display a response to input printf("Buffer is %.*s!\n", i, Buffer); } 

printf()格式字符串中的这种表示法指定了要显示的字符串的最大长度,并且不需要空终止(尽管空终止最终是最好的方法 - 至少一旦你离开这个循环)。

while循环比简单的if更合理,而且这个版本确保你不会溢出缓冲区的末尾(但不能确保为尾随NUL '\0'留下足够的空间。如果你想处理它,使用sizeof(Buffer) - 1然后在循环后添加NUL。

由于Buffer未初始化,因此它以所有9个垃圾值开始。 从观察到的输出,第2,第3,第4,第5,第6,第7,第8和第2个直接下一个存储器位置(arrays外)元素明显是'T''T''W''\0''\0''=''\0''\0''\0'

字符串消耗所有字符,直到它们看到NULL字符。 这就是为什么在每次迭代中,当逐个分配数组元素时,缓冲区被打印到存在垃圾NULL的部分。

也就是说,如果字符数组不以'\0'结尾,则字符串具有未定义的行为。 您可以通过在缓冲区末尾为'\0'留出额外空间来避免这种情况。

您可能还想查看使用stringstream