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

时间:2008-11-06 23:06:07

标签: c string cstring null-terminated

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

  1. 当我执行printf来查看Buffer中的内容时,它确实填满了但是我最后得到了垃圾字符
  2. 尽管被声明为char Buffer [8];
  3. ,它不会停止在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 is 1┬┬w!
    tagBuffer is 12┬w!
    tagBuffer is 123w!
    tagBuffer is 1234!
    tagBuffer is 12345!
    tagBuffer is 123456=!
    tagBuffer is 1234567!
    tagBuffer is 12345678!

    tagBuffer是123456789!

7 个答案:

答案 0 :(得分:28)

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

分配1个额外的字符来保存\ 0。

也是明智之举

答案 1 :(得分:8)

您传递给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);

}

答案 2 :(得分:3)

除了之前关于零终止的评论之外,您还必须承担不溢出自己的缓冲区的责任。它不会停留在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++; 

}

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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留下足够的空间{ {1}}。如果你想处理它,请使用'\0',然后在循环后添加NUL。

答案 5 :(得分:0)

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

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

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

答案 6 :(得分:-1)

您可能还想查看使用stringstream