我有一个char数组缓冲区,用于存储用户将逐个输入的字符。我的代码在下面有效,但有一些我无法弄清楚的故障:
有人可以向我解释发生了什么,也许我可以解决这个问题?感谢。
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!
答案 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
。