c - gets() 在 scanf 之后如何工作?

c - how gets() work after scanf?

我有两个问题:

  1. 为什么只有当我在“%d”中执行 space 时 --> scanf("%d ", &num); 它才有效?

我在 scnaf 和 gets 之间尝试了 fflush(stdin) \ _flushall() 但它不起作用,它跳过了 gets。

  1. 当我执行 space 时,它首先执行 scanf,然后执行 gets,然后打印数字和字符串。
void main()
{
    char ch, str[10];
    int num;
    printf("Enter your number : ");
    scanf("%d ", &num);
    printf("%d\n",num);
    gets(str);
    puts(str);
    system("pause");
}
  1. why only when i do space in "%d " --> scanf("%d ", &num); it works?

scanf("%d", &num);"%d" 之后没有 space,在读取数字后停止扫描。所以输入 123Enter, '\n' 保留在 stdin 中用于下一个输入函数,例如现在的非标准 gets()gets() 读取单个 '\n' 和 return。通过添加 space,scanf("%d ", &num); 会在数字后消耗白色-space 并且不会 return 直到在数字后输入非白色-scape。

  1. When I do the space, it first does scanf then the gets and after that it print the number and print the string.

通过添加一个space,scanf("%d ", &num);不会return,直到在数字后输入非白色-space(如'a'下列)。由于 stdin 通常是行缓冲的,这意味着需要先输入 2 行。 123输入 a bc输入.


建议改为使用 fgets() 来读取 的用户输入。

char str[10*2]; // no need for such a small buffer
int num;
printf("Enter your number : ");
fflush(stdout);
fgets(str, sizeof str, stdin);
sscanf(str, "%d", &num);
printf("%d\n",num);

printf("Enter data : ");
fflush(stdout);
fgets(str, sizeof str, stdin);
fputs(str, stdout);

更健壮的代码会检查 fgets(), sscanf() 的结果并使用 strtol() 而不是 sscanf()

C 常见问题解答涵盖了 scanf 中的所有这些问题。请参阅 Why does everyone say not to use scanf? What should I use instead? 和相关条目。通常,您将使用 fgets 然后处理结果行,例如使用 sscanf 并检查 sscanf 是否成功。这避免了留下未解析的输入并冒着无限循环的风险。

int number;
char line[255];

fgets( line, sizeof(line), stdin );
if( sscanf( line, "%d", &number ) != 1 ) {
    fputs("That doesn't look like a number.\n", stdin);
}

请注意,fgets 将读取到换行符 或您的缓冲区可以容纳的最大容量 。如果该行大于您的缓冲区,它可能只读取该行的一部分。接下来从输入中读取将获得该行的其余部分。有一些方法可以避免这种情况,例如 the POSIX getline function,但至少您不会陷入无限循环。

让我们解读一些评论。

永远不要使用 gets。使用 fgets.

您不使用 gets 的原因是无法限制从 stdin 读取的数据量。这意味着用户可以溢出缓冲区造成严重破坏。

char buffer[32];

// What the line is more than 31 characters?
gets(buffer);

fgets() 占用缓冲区的大小并且最多读取那么多字符。这可以防止缓冲区溢出。

char buffer[32];

// If there's more than 31 characters it will stop reading.
// The next read of stdin will get the rest of the line.
fgets( buffer, sizeof(buffer), stdin );

"C 中没有 gets() 函数"

是的, C 中的一个gets()函数

是的,没有 gets() C 中的函数。

这取决于你说的是哪个 C。

有些人说 "C" 是指 C11,即当前标准。其他人说 "C" 表示 C99 是以前的标准。有些仍然坚持原始标准 C90。 C90中有一个gets()函数。它在 C99 中被弃用。它已从 C11 中的语言中删除。

C 编译器和文档远远落后于标准。许多人仍在致力于全面支持 C99。如果你工作到 C11,你会对缺乏支持感到非常惊讶。如果您希望您的代码适用于大多数编译器,请写入 C99。

总之,不要使用gets