Помогите с синтаксисом C scanf - PullRequest
3 голосов
/ 16 сентября 2010

Когда я запускаю следующий фрагмент, он работает до второго вопроса. Затем он объединяет запросы «Является ли клиент студентом (y / n) \ n» и «Сколько времени в кино? Если после этого предпринять какое-либо действие, программа перестает работать. Что я сделал не так? (я уверен, что это связано с синтаксисом)

int A,B,C,D,age,time;
char edu, ddd;

printf ("What is the customer's age? \n");
scanf("%d", &age);

printf ("Is the customer a student? (y/n) \n");
scanf("%c", &edu);

printf ("What is the movies time? (in hours) \n");
scanf("%d", &time);

printf ("Is the movie 3-D? (y/n) \n");
scanf("%c", &ddd);

Ответы [ 6 ]

4 голосов
/ 16 сентября 2010

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

Один из способов избежать - использовать fgets для чтения ввода как строки и затем извлечь то, что вы хотите, используя sscanf.

Другой способпотреблять перевод строки будет scanf("%c%*c",&edu);.%*c будет читать новую строку из буфера и удалять ее.

4 голосов
/ 16 сентября 2010

Возможно, вам нужно съесть дополнительный ввод из stdin после каждого сканирования, чтобы он не зависал в буфере и не вызывал сканирование для получения буферизованных данных.

Это потому, что перевод строки после нажатия на клавишу ввода после первой текстовой записи остается в буфере и является допустимой записью для формата "% c" - если вы посмотрите на значение "edu", вы увидите, что это символ новой строки .

2 голосов
/ 16 сентября 2010

Возникли проблемы с scanf и "% c", см., Например: @jamesdlin. «time» - это имя функции C-Standard-Lib, лучше использовать другое имя, например:

int A,B,C,D,age=0,timevar=0;
char edu=0, ddd=0, line[40];

printf ("What is the customer's age? \n");
if( fgets(line,40,stdin) && 1!=sscanf(line,"%d", &age) ) age=0;

printf ("Is the customer a student? (y/n) \n");
if( fgets(line,40,stdin) && 1!=sscanf(line,"%c", &edu) ) edu=0;

printf ("What is the movies time? (in hours) \n");
if( fgets(line,40,stdin) && 1!=sscanf(line,"%d", &timevar) ) timevar=0;

printf ("Is the movie 3-D? (y/n) \n");
if( fgets(line,40,stdin) && 1!=sscanf(line,"%c", &ddd) ) ddd=0;

В конце ваши переменные имеют определенный контент, 0 для ошибки ввода,! = 0 в противном случае.

2 голосов
/ 16 сентября 2010

Вы можете добавить пробел перед% c. Это необходимо, потому что, в отличие от других спецификаторов преобразования, он не пропускает пробелы. Поэтому, когда пользователь вводит что-то вроде «10 \ n» в качестве возраста, первое значение scanf читается до конца 10. Затем% c читает символ новой строки. Пробел говорит scanf пропустить все текущие пробелы перед чтением символа.

printf ("What is the customer's age? \n");
scanf("%d", &age);

printf ("Is the customer a student? (y/n) \n");
scanf(" %c", &edu);

printf ("What is the movies time? (in hours) \n");
scanf("%d", &time);

printf ("Is the movie 3-D? (y/n) \n");
scanf(" %c", &ddd);
1 голос
/ 16 февраля 2013

Используйте оператор fflush (stdin);

, чтобы очистить буферную память stdin перед чтением любых символьных данных

, иначе он будет считывать значение ключа ввода первого scanf во второмзсапЕ.

0 голосов
/ 27 декабря 2013

Я попробовал вашу программу, и кажется, что после ввода возраста, когда я нажимаю клавишу ввода, он рассматривает это как ввод для следующего scanf (т.е. для & edu) и аналогично для третьего и четвертого вопроса.Мое решение может быть наивным, но вы можете просто использовать буфер scanf после каждого, чтобы поглотить «Enter».Или просто сделайте это

scanf(" %c", &variable);

(Любой пробел в строке формата заставит scanf поглотить все последующие последовательные пробелы).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...