Проблема с fgets()/gets() при вводе N строк. Не принимает ввод в исходной позиции

Мне нужно получить ввод для n (введенных пользователем) строк. Для этого я начинаю с определения двумерного массива char str[ ][ ].
Я использовал цикл for, получая ввод от пользователя, и пробовал gets(), fgets() оба. В примере кода я использовал gets().
Но он всегда принимает ввод для n-1 строк, то есть на 1 меньше, чем хочет ввести пользователь.
При дальнейшей проверке я обнаружил, что программа не принимает ввод для 0-й строки, т. е. исходной строки.

Мой код:

#include <stdio.h>
int main(void){
int i, n;

printf("how many string you want to enter: ");
scanf("%d", &n);

char str[n][60];

printf("start entering strings:\n ");

for(i=0;i<n;i++){     
    gets(str[i]);     //have used here fgets() also
}

puts(str[0]);         //no output for Oth string
return 0;
}

Вывод:

how many string you want to enter:

Пользовательский ввод - 3

how many string you want to enter: 3
start entering strings:

Окончательный результат:

how many string you want to enter: 3
start entering strings:
 abc
bcd

Здесь программа завершается после получения ввода только для 2 строк и отсутствия вывода для puts(str[0]);

Хотя входные данные с scanf() как scanf("%s", str[i]); работали отлично.
Я хочу знать, почему использование gets(), fgets() не сработало.


person Vartika    schedule 27.10.2018    source источник
comment
Прежде всего, никогда никогда не используйте gets. Это опасная функция и поэтому даже был удален из стандарта C.   -  person Some programmer dude    schedule 27.10.2018
comment
тоже пробовали fgets. проблема в том, что он не принимает ввод для str[0]   -  person Vartika    schedule 27.10.2018


Ответы (2)


Проблема не в fgets (или gets в этом отношении). Проблема в вашем предыдущем вызове scanf.

Когда вы завершите ввод числа клавишей Enter, эта клавиша Enter будет добавлена ​​во входной буфер как новая строка. Таким образом, после того, как scanf прочитает число, следующий символ, оставшийся во входном буфере, будет этой новой строкой. И это первый символ, который fgets будет читать как пустую строку. Таким образом, он прочитает все строки, но первая будет считаться пустой.

И именно поэтому вы похоже не получаете никакого вывода, потому что нет печатных символов для печати. Все, что вы получите, это пустая строка.

person Some programmer dude    schedule 27.10.2018
comment
Я думаю, самая большая проблема в том, что я использую неправильный текст для изучения C. :( - person Vartika; 27.10.2018
comment
поможет ли мне сообщество в выборе правильного источника? - person Vartika; 27.10.2018
comment
@Vartika выберите тег [c] и нажмите «Узнать больше», есть много советов, включая ресурсы и книги: stackoverflow.com/tags /с/информация. - person David Ranieri; 27.10.2018

Вам нужно использовать оставшийся буфер, оставленный scanf:

scanf("%d", &n);
char str[n][60];
int c;
while ((c = fgetc(stdin)) != '\n' && c != EOF);
printf("start entering strings:\n ");

Вы можете избежать уродливого цикла сброса, используя fgets и strtol вместо scanf:

char buf[32];
int i, n = 0;

printf("how many string you want to enter: ");
if (fgets(buf, sizeof buf, stdin)) {
    n = (int)strtol(buf, NULL, 10);
}

char str[n][60];
printf("start entering strings:\n ");
person David Ranieri    schedule 27.10.2018
comment
Я не понял. - person Vartika; 27.10.2018
comment
У вас есть хорошее объяснение от @Someprogrammerdude в другом ответе. - person David Ranieri; 27.10.2018
comment
@asynts, вот почему я предлагаю fgets и strtol, вы также можете проверить правильность ввода, используя второй параметр, но это остается в качестве упражнения для OP :) - person David Ranieri; 27.10.2018