问题描述
我的程序应该通过stdin接受输入,并将字符串存储到大小为SIZE
的数组中。
当我输入7个或更多值时,会出现我的问题;当程序循环运行时,超出缓冲区大小的值仍会被使用,同时用标准输入中剩余的内容buf
不断填充(至少,我认为它是这样工作的)。
#define SIZE 8
char *readLine(char *buf,size_t size) {
printf("$ ");
fgets(buf,size,stdin);
return buf;
}
int main() {
char *buf = malloc(SIZE * sizeof(char));
for (;;) {
readLine(buf,SIZE);
printf("> %s",buf);
}
}
我得到的输出分别测试了6、7和8的输入大小:
$ abcdef
> abcdef
$ abcdefg
> abcdefg$ >
$ abcdefgh
> abcdefg$ > h
我不了解的事情:
解决方法
为什么第7个值会使程序的输出看起来很奇怪?我以为第7个字符加上空字符可以正常工作?
fgets
不会读取过多的输入(超出了您提供的缓冲区大小,但为空字节排除了一个字节空间)。因此,字符h
留在输入流中,然后在下一次调用fgets
时被占用-读取为h
和换行符\n
。读取换行符后,fgets
终止读取其他输入。
为什么buf会填充超出SIZE大小(在这种情况下为8)的值?
不是。如前所述,剩余的输入将被读取,因此它具有这种外观。
由此,我可以进行简单的更改/添加来实现自己想要的功能吗?
您可以检查fgets
读取的缓冲区是否具有换行符char;如果没有,请读取并忽略输入流中的剩余字节。
您可以这样做:
void discard(const char *buf)
{
if(strchr(buf,'\n') == NULL) {
/* No newline found,so read & discard everything.
while(getchar() != '\n');
}
}
char *readLine(char *buf,size_t size) {
printf("$ ");
if (fgets(buf,size,stdin) != NULL) {
discard(buf);
}
return buf;
}