末尾带有垃圾字符的字符串数组
我有一个字符数组缓冲区,用于存储用户将一一输入的字符。 我下面的代码可以工作,但有一些我无法弄清楚的小故障:
- 当我执行 printf 来查看 Buffer 中的内容时,它确实填满了,但最后我得到了垃圾字符,
- 尽管它是 8 个字符,但它不会停止在 8 个字符处。声明为 char Buffer[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!
I have a char array buffer that I am using to store characters that the user will input one by one. My code below works but has a few glitches that I can't figure out:
- when I execute a printf to see what's in Buffer, it does fill up but I get garbage characters at the end
- it won't stop at 8 characters despite being declared as char Buffer[8];
Can somebody please explain to me what is going on and perhaps how I could fix this? Thanks.
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);
}
Output:
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 is 123456789!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您必须以
\0
字符结束字符串。 这就是为什么它们被称为零终止字符串。分配 1 个额外的字符来保存
\0
也是明智的做法。You have to end the string with a
\0
character. That's why they are called zero terminated strings.It is also wise to allocate 1 extra char to hold the
\0
.您传递给 printf() 函数的唯一内容是指向字符串第一个字符的指针。 printf() 无法知道数组的大小。 (它甚至不知道它是否是一个实际的数组,因为指针只是一个内存地址。)
printf() 和所有标准 C 字符串函数都假设字符串末尾有一个 0。 例如,printf() 会在内存中不断打印字符,从传递给函数的字符开始,直到它达到 0。
因此,您应该将代码更改为如下所示:
The only thing you are passing to the printf() function is a pointer to the first character of your string. printf() has no way of knowing the size of your array. (It doesn't even know if it's an actual array, since a pointer is just a memory address.)
printf() and all the standard c string functions assume that there is a 0 at the end of your string. printf() for example will keep printing characters in memory, starting at the char that you pass to the function, until it hits a 0.
Therefore you should change your code to something like this:
除了前面关于零终止的评论之外,您还必须承担不溢出自己的缓冲区的责任。 它不会在 8 个字符处停止,因为您的代码不会停止! 您需要类似以下内容(顺应 Jeremy 的建议):
换句话说,无论环境试图向您推送什么,请确保在达到最大长度时停止接受数据。
In addition to the previous comments about zero termination, you also have to accept responsibility for not overflowing your own buffer. It doesn't stop at 8 characters because your code is not stopping! You need something like the following (piggy-backing onto Jeremy's suggestion):
In other words, make sure to stop accepting data when the maximum length has been reached, regardless of what the environment tries to push at you.
如果您使用 C 或 C++ 编程,则必须记住:
1) 字符串以 \0 字符结束。
2) C 对字符串没有边界检查,它们只是字符数组。
If you are programming in C or C++, you have to remember that:
1) the strings are finished with a \0 character.
2) C does not have boundary check at strings, they are just character arrays.
奇怪的是,没有人提到这种可能性:
printf() 格式字符串中的这种表示法指定要显示的字符串的最大长度,并且不需要空终止(尽管空终止最终是最好的方法 -至少一旦你离开这个循环)。
while
循环比简单的if
更合理,并且此版本可确保您不会溢出缓冲区的末尾(但不能确保为如果您想处理尾随 NUL'\0'
,请使用sizeof(Buffer) - 1
,然后在循环后添加 NUL。It's odd that no-one has mentioned this possibility:
This notation in the printf() format string specifies the maximum length of the string to be displayed, and does not require null termination (though null termination is ultimately the best way to go -- at least once you leave this loop).
The
while
loop is more plausible than a simpleif
, and this version ensures that you do not overflow the end of the buffer (but does not ensure you leave enough space for a trailing NUL'\0'
. If you want to handle that, usesizeof(Buffer) - 1
and then add the NUL after the loop.由于 Buffer 未初始化,因此它以所有 9 个垃圾值开始。
从观察到的输出来看,第 2 个、第 3 个、第 4 个、第 5 个、第 6 个、第 7 个、第 8 个和 2 个紧邻的下一个内存位置(数组外部)元素显然是
'T'
、'T'< /code>,
'W'
,'\0'
,'\0'
,'='
,'\0'
、'\0'
、'\0'
。字符串会消耗所有字符,直到看到 NULL 字符。 这就是为什么在每次迭代中,当数组元素被逐一分配时,缓冲区会被打印到存在垃圾 NULL 的部分。
也就是说,如果字符数组不以
'\0'
结尾,则 string 具有未定义的行为。 您可以通过在缓冲区末尾添加额外的'\0'
空间来避免这种情况。Since
Buffer
is not initialized, it starts with all 9 garbage values.From the observed output, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th and 2 immediate next memory location(outside the array) elements are clearly
'T'
,'T'
,'W'
,'\0'
,'\0'
,'='
,'\0'
,'\0'
,'\0'
.Strings consume all the characters up until they see NULL character. That is why, in every iteration, as the array elements are assigned one by one, buffer is printed up to the part where a garbage NULL is present.
That is to say, string has an undefined behavior if the character array doesn't end with
'\0'
. You can avoid this by having an extra space for'\0'
at the end of the buffer.您可能还想研究使用
stringstream
。You might also want to look into using a
stringstream
.