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

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

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

Начнем с того, что никогда не используйте Когда-либоgets. Это опасная функция, и поэтому он даже был удален из стандарта C.

Some programmer dude 27.10.2018 12:48

также попробовали fgets. проблема в том, что он не принимает ввод для str [0]

Vartika 27.10.2018 12:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
2
247
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам нужно использовать оставшийся буфер, оставленный 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 ");

Я не понял.

Vartika 27.10.2018 13:08

У вас есть хорошее объяснение от @Someprogrammerdude в другом ответе.

David Ranieri 27.10.2018 13:10

@asynts, вот почему я предлагаю fgets и strtol, вы также можете проверить, действителен ли ввод, используя второй параметр, но это оставлено как упражнение для OP :)

David Ranieri 27.10.2018 13:36
Ответ принят как подходящий

Проблема не в fgets (или gets, если на то пошло). Проблема заключается в вашем предыдущем звонке на scanf.

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

Вот почему вы не используете казаться, чтобы получить какой-либо вывод, потому что нет печатаемых символов для печати. Все, что вы получаете, - это пустая строка.

Я думаю, самая большая проблема - я использую неправильный текст для изучения C. :(

Vartika 27.10.2018 13:13

сообщество поможет мне выбрать правильный источник?

Vartika 27.10.2018 13:17

@Vartika выберите тег [c] и нажмите «Узнать больше», есть много советов, включая ресурсы и книги: stackoverflow.com/tags/c/info.

David Ranieri 27.10.2018 13:29

Другие вопросы по теме