Предполагая, что код не блокирует , а следующая строка запускает немедленно (как вы указали в начале вопроса и в комментарии ), у вас есть общая проблема при смешивании нелинейного и строчного ввода.
Что происходит, если в буфере остается новая строка, и fgets видит это, читает и возвращает вместо того, чтобы делать то, что вам действительно нужно: игнорировать это, а затем читать строку.
Решение состоит в том, чтобы просто выполнить часть игнорирования самостоятельно, а затем вызвать fgets:
#include <stdio.h>
#include <string.h>
FILE* ignoreline(FILE* stream) {
for (int c; (c = fgetc(stream)) != EOF;) {
if (c == '\n') break;
}
return stream;
}
void example_use() {
char buf[1000];
ignoreline(stdin);
fgets(buf, sizeof buf, stdin);
// or, since it returns the stream, can be more compact:
fgets(buf, sizeof buf, ignoreline(stdin));
}
int main() { // error handling omitted
int n;
printf("Enter a number: ");
scanf("%d", &n);
char buf[1000];
printf("Enter a line: ");
ignoreline(stdin); // comment this line and compare the difference
fgets(buf, sizeof buf, stdin);
*strchr(buf, '\n') = '\0';
printf("You entered '%s'.\n", buf);
return 0;
}
Обратите внимание, что также распространено и рекомендуется "соединять" линию игнорирования со scanf (или другим входом, не основанным на строках), чтобы превратить это в ввод на строковой основе. В этом случае вы можете изменить его, чтобы вы могли определить разницу между вводом «42 abc» и «42» (в случае «Введите число»). Некоторые люди просто используют fgets везде, а затем анализируют эту строку с помощью sscanf, и хотя это работает, в этом нет необходимости.