Получает () не работает

Я пытаюсь использовать gets() для получения строки от пользователя, но программа, кажется, проходит прямо через gets(). Пользователь не делает паузы для ввода. Почему gets() ничего не делает?

char name[13];
printf("Profile name: ");
gets(name);
printf("\n%s", name);

person Ace    schedule 30.10.2013    source источник
comment
Вы пробовали сканф? Также вы уверены, что длина ввода не превышает 12 символов. Какие тестовые значения вы использовали?   -  person TheDude    schedule 30.10.2013
comment
@DerekDrummond 12 символов ввода, последний должен быть '\0'.   -  person Kevin    schedule 30.10.2013
comment
пожалуйста, используйте fgets(name, sizeof name, stdin) вместо gets() вопрос дан много раз, см. один из ответов stackoverflow.com/questions/7231349/   -  person Gangadhar    schedule 30.10.2013
comment
Хороший звонок, я забыл об этом персонаже-страже.   -  person TheDude    schedule 30.10.2013
comment
Да, я использовал scanf, и он работает.   -  person Ace    schedule 30.10.2013
comment
Также не используйте scanf для чтения строк. Просто используйте fgets.   -  person Kninnug    schedule 30.10.2013
comment
@Kninnug Если я ранее использовал scanf в своем коде, будет ли по-прежнему пропускаться fgets?   -  person Ace    schedule 30.10.2013
comment
Я считаю, что вы можете оставить пробел в конце формата scanf, чтобы он использовал любой пробел (например, завершающую новую строку) во входных данных. Но не цитируйте меня по этому поводу.   -  person Kninnug    schedule 30.10.2013
comment
Я попробовал fgets(name, sizeof name, stdin), но его пропустили. Печально, что функция gets() раньше была такой простой, а теперь заменена чем-то громоздким.   -  person Yan King Yin    schedule 20.02.2016


Ответы (6)


У вас много проблем с использованием gets()

Вместо этого выберите fgets()

fgets(name,13,stdin);  

См. этот вопрос SO Почему функция настолько опасна, что ее нельзя использовать?

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

Вы можете изменить строку формата scanf, чтобы учесть ее: scanf("%d *[^\n]", &N);

*[^\n] говорит игнорировать все после вашего целочисленного ввода, которое не является новой строкой, но ничего не делать с новой строкой (пропустить ее).

Когда вы используете scanf("%d",&num), вы нажимаете 13, а enter и 13 сохраняются в num, а символ newline все еще находится во входном буфере, когда вы читаете fgets из stdin, он обрабатывает \n как введенные вами данные, а оператор fgets() пропускается.

Вы не можете очистить входной буфер, однако вы можете сделать это fseek(stdin,0,SEEK_END); добавить это перед каждым оператором fgets

person niko    schedule 30.10.2013
comment
@Andre, не могли бы вы опубликовать свой полный код? это работает здесь - person niko; 30.10.2013
comment
void createProfile() {имя символа[13]; printf(Имя профиля: ); fgets(имя,13,стандартный ввод); printf(\n%s, имя); } - person Ace; 30.10.2013
comment
вы использовали scanf в какой-либо части вашего кода @Andre, потому что scanf() читает именно то, что вы просите; он оставляет все остальное непрочитанным, особенно новую строку после данных. - person niko; 30.10.2013
comment
Да, я использовал его несколько раз раньше. Так вы говорите, что я должен использовать только fgets? - person Ace; 30.10.2013
comment
Предложите fgets(name, sizeof(name), stdin). - person chux - Reinstate Monica; 30.10.2013
comment
На самом деле не думайте, что вам нужен пробел в scanf("%d *[^\n]",&N);, так как он будет потреблять новую строку после целого числа. - person chux - Reinstate Monica; 30.10.2013
comment
Спрашивающий хочет получить %s, а не %d. С цифрами проще работать. Я также хочу получить строку без хвоста /n, и я хочу получить нулевую строку, если пользователь просто нажал клавишу ввода. - person Yan King Yin; 20.02.2016

Вызовите getchar() перед вызовом gets() или fgets(). Поскольку gets() или fgets() пропускаются из-за уже присутствующего '\n' из предыдущих входных данных в stdin, вызов getchar() приведет к пропуску самого себя вместо gets() или fgets() или любой другой подобной функции. . Но помните, что это скорее хак, а не стандартное решение (я так думаю), а также запрещено использование gets().

        printf("\nEnter a String: ");
        getchar();
        //fgets(inputString, 100, stdin);
        gets(inputString);
        printf("\n%s", inputString);
person thisisprateek    schedule 25.03.2017

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

Вместо этого используйте fgets().

person Nikos C.    schedule 30.10.2013
comment
gets также был официально удален в C11 и устаревшим в C++. - person Linuxios; 30.10.2013

Используйте fflush(stdin); перед получением ()

person Aadil Ansari    schedule 10.04.2019
comment
Это решение, которое сработало для меня, другое - нет. спасибо @Aadil Ansari - person Joe Gasewicz; 24.12.2020

Взгляните на gets() справочник.

Получить строку со стандартного ввода

Считывает символы со стандартного ввода (stdin) и сохраняет их как строку C в str до тех пор, пока не будет достигнут символ новой строки или конец файла.

Символ новой строки, если он найден, не копируется в строку str.

Завершающий нулевой символ автоматически добавляется после символов, скопированных в str.

Обратите внимание, что gets сильно отличается от fgets: get не только использует stdin в качестве источника, но и не включает конечный символ новой строки в результирующую строку и не позволяет указать максимальный размер для str (что может привести к переполнению буфера).

Таким образом, в основном gets() не только небезопасен (может привести к переполнению буфера), но и считывает содержимое входного буфера.

Я рекомендую вам использовать fgets(), но если вам нужно быстрое (и ленивое и глупое) решение, просто очистите входной буфер:

char name[13];
printf("Profile name: ");
fflush(stdin);
gets(name);
printf("\n%s", name);
person fvdalcin    schedule 30.10.2013
comment
Вызов fflush(stdin) является неопределенным поведением в C. - person digital_revenant; 30.10.2013
comment
Вы правы, он предназначен для использования с выходными буферами. Однако некоторые компиляторы реализуют fflush(stdin) как расширение. Он работает так, как ожидалось, но ставит под угрозу портативность. - person fvdalcin; 30.10.2013
comment
Да, однако стандарт языка рассматривает это как неопределенное поведение. И его использование не должно поощряться. - person digital_revenant; 30.10.2013

Добавьте эту функцию ниже в свой код и наслаждайтесь ею.

string GetString()
{
   char ch;
   string Line="";

   while(1)
   {
       ch=getchar();

       if(ch=='\n')
          break;
       else
          Line+=ch;
    }

    return Line;
}

Эта функция также может работать со всеми пробелами и возвратами!!!

person PouriaDiesel    schedule 11.04.2017