使用输入缓冲区的代码未按预期工作

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。这就是结果。

  1. 您应该始终检查 fgets 的 return 值。如果输入不包含 EOL,循环将永远不会退出。

  2. 传递给 fgets 的缓冲区大小包括 returned \0,因此您正在读取 255 个字符,而不是 256 个。

  3. 如果你想读取 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 */
        }
    }