使用输入缓冲区的代码未按预期工作
Code to consume input buffer not working as espected
我有这段代码应该将用户输入的字符串截断为 256 个字符,并防止它“溢出”到后续的 fgets() 函数中。
直到今天它都运行良好。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <ctype.h>
#include <string.h>
int main(){
printf("\nEnter a new string.\n");
char string[256];
do
{
fgets(string,256,stdin);
} while (strlen(string) > 0 && string[strlen(string) - 1] != '\n');
printf("\n\n stringa %s\n", string);
}
例如,如果我输入一个长度超过 256 个字符的字符串,例如
Qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
我希望它打印:
Qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxc
而是打印:
cvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
这是为什么?我该如何解决?
fgets 将读取直到缓冲区已满或达到 EOL (\n)。
代码中的循环将调用 fgets,直到结果包含 EOL。
所以:第一次通过它读取缓冲区直到满,然后继续
循环;第二次通过它从当前点开始读取,直到它到达 EOL。这就是结果。
您应该始终检查 fgets 的 return 值。如果输入不包含 EOL,循环将永远不会退出。
传递给 fgets 的缓冲区大小包括 returned \0,因此您正在读取 255 个字符,而不是 256 个。
如果你想读取 256 个字符,然后丢弃直到 \n 的输入,那么做:
char string[257]; /* room for 256+[=10=] */
string[0] = 0; /* set string empty in case of no input */
if (fgets(string, sizeof(string), stdin)) { /* read */
if (!strchr(string, '\n')) { /* didn't pick up EOL */
do {
int c = fgetc(stdin); /* get characters */
} while (c >= 0 && c != '\n'); /* until EOL or EOF */
}
}
我有这段代码应该将用户输入的字符串截断为 256 个字符,并防止它“溢出”到后续的 fgets() 函数中。 直到今天它都运行良好。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <ctype.h>
#include <string.h>
int main(){
printf("\nEnter a new string.\n");
char string[256];
do
{
fgets(string,256,stdin);
} while (strlen(string) > 0 && string[strlen(string) - 1] != '\n');
printf("\n\n stringa %s\n", string);
}
例如,如果我输入一个长度超过 256 个字符的字符串,例如
Qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
我希望它打印:
Qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxc
而是打印:
cvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
这是为什么?我该如何解决?
fgets 将读取直到缓冲区已满或达到 EOL (\n)。
代码中的循环将调用 fgets,直到结果包含 EOL。 所以:第一次通过它读取缓冲区直到满,然后继续 循环;第二次通过它从当前点开始读取,直到它到达 EOL。这就是结果。
您应该始终检查 fgets 的 return 值。如果输入不包含 EOL,循环将永远不会退出。
传递给 fgets 的缓冲区大小包括 returned \0,因此您正在读取 255 个字符,而不是 256 个。
如果你想读取 256 个字符,然后丢弃直到 \n 的输入,那么做:
char string[257]; /* room for 256+[=10=] */
string[0] = 0; /* set string empty in case of no input */
if (fgets(string, sizeof(string), stdin)) { /* read */
if (!strchr(string, '\n')) { /* didn't pick up EOL */
do {
int c = fgetc(stdin); /* get characters */
} while (c >= 0 && c != '\n'); /* until EOL or EOF */
}
}