C 结尾带有垃圾字符的字符串数组
我有一个字符数组缓冲区,用来存储用户将逐个输入的字符。我下面的代码可以正常工作,但有一些我无法解决的小故障:C 结尾带有垃圾字符的字符串数组,c,string,cstring,null-terminated,C,String,Cstring,Null Terminated,我有一个字符数组缓冲区,用来存储用户将逐个输入的字符。我下面的代码可以正常工作,但有一些我无法解决的小故障: 当我执行printf以查看缓冲区中的内容时,缓冲区确实填满了,但我在最后得到了垃圾字符 尽管声明为字符缓冲区[8],但它不会在8个字符处停止 有人能给我解释一下发生了什么事,也许我该如何解决这个问题?谢谢 char Buffer[8]; //holds the byte stream int i=0; if (/* user input event has occurred */)
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为1┬┬W
tagBuffer是12┬W
tagBuffer是123w!
tagBuffer是1234!
tagBuffer是12345!
tagBuffer是123456=!
tagBuffer是1234567!
tagBuffer是12345678!
tagBuffer是123456789 必须以\0字符结尾字符串。这就是为什么它们被称为以零结尾的字符串
分配1个额外的字符来保存\0也是明智的。传递给printf()函数的唯一内容是指向字符串第一个字符的指针。printf()无法知道数组的大小。(它甚至不知道它是否是实际数组,因为指针只是一个内存地址。) printf()和所有标准c字符串函数都假定字符串末尾有一个0。例如,printf()将保持在内存中打印字符,从传递给函数的字符开始,直到到达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);
}
<>如果你在C或C++编程,你必须记住: 1) 字符串以\0字符结束。
2) C对字符串没有边界检查,它们只是字符数组。您可能还想研究使用
stringstream
除了前面关于零终止的注释外,您还必须承担不溢出自己缓冲区的责任。它不会在8个字符处停止,因为您的代码没有停止!您需要以下内容(借助Jeremy的建议):
#定义数据长度8
#定义缓冲区长度(数据长度+1)
字符缓冲区[缓冲区长度]//保存字节流
int charPos=0//索引到要填充的下一个字符位置
然而(charPos奇怪的是,没有人提到这种可能性:
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);
}
char缓冲区[8];//保存字节流
int i=0;
而(i
printf()格式字符串中的这个表示法指定了要显示的字符串的最大长度,并且不需要null终止(尽管null终止最终是最好的方式——至少在您离开这个循环之后)
while
循环比简单的if
循环更合理,此版本可确保不会溢出缓冲区的末尾(但不能确保为尾部NUL'\0'
留出足够的空间)。如果要处理此问题,请使用sizeof(缓冲区)-1,然后在循环后添加NUL。由于缓冲区未初始化,因此它从所有9个垃圾值开始。
从观察到的输出来看,第二、第三、第四、第五、第六、第七、第八和第二个下一个内存位置(在数组之外)元素显然是'T'
,'T'
,'W'
,'\0'
,'='
,'\0'
,'\0'
字符串会一直使用所有字符,直到看到空字符为止。这就是为什么在每次迭代中,当数组元素逐个赋值时,缓冲区会打印到存在垃圾空字符的部分
也就是说,如果字符数组不是以'\0'
结尾,字符串就有一个未定义的行为。您可以通过在缓冲区的末尾为'\0'
留出额外的空间来避免这种情况。太棒了。谢谢。不过,只有一个问题:缓冲区[8]有什么意义?缓冲区[8]告诉编译器为数组留出8字节的内存。字符串可以短于此(例如,通过执行“buffer[4]=0;”),但不能(或不应该)长。buffer[8]是7个字符和一个终止符的缓冲区;-).stringstream与C无关。@Jonathan:我假设DATA_LENGTH是应用程序域的主要概念,Buffer的大小是依赖值,反之亦然。DATA_LENGTH的其他用途可能与Buffer无关,因此不应该提及它。@joel.neely,尽管上面的代码不正确(虽然语句注释位置不正确),但您应该获得一次向上投票,因为将下一个字符设置为“\0”是解决方案。我建议编辑为“Buffer[i]=charInput;Buffer[i+1]='\0';i++;”。为清楚起见,尽管您的实现没有错误,但调试起来更困难,因为您在同一行中设置了两个变量(我想是风格的问题)。
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);
}