2015-09-05 7 views
1

Я сделал программу, чтобы узнать, как вы себя зовете, если вы были мужчиной или женщиной, сколько вам лет, и если я буду называть вас миссис, госпожа, мистер или просто вашим полным именем, в зависимости от предыдущих условий , Когда я выбираю свой пол как женщину и вводю имя, фамилию и возраст, превышающий или равный 20, я спрашиваю, женился ли этот человек, однако по какой-то причине программа пропускает getchar и просто заканчивает программу.Почему getchar() не получает ввода?

Вот код:

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char gender; 
    char fName[15]; 
    char lName[15]; 
    char mar; 
    char str[] = "Then I shall call you"; 
    int age = 0; 

    printf("What is your gender (M or F): "); 
    gender = getchar(); 

    printf("First name: "); 
    scanf("%s", fName); 
    //fgets(fName, 16, stdin); 
    //fName[strcspn(fName, "\n")] = 0; 

    printf("Last name: "); 
    scanf("%s", lName); 
    //fgets(lName, 16, stdin); 
    //lName[strcspn(lName, "\n")] = 0; 

    printf("Age: "); 
    scanf("%d", &age); 

    puts(""); 

    if(gender == 'F' || gender == 'f') 
    { 
     if(age >= 20) 
     { 
      printf("Are you married, %s (y or n)?: ", fName); 

      //scanf("%c", &mar); 
      mar=getchar(); 

      printf("%c\n", mar); 

      if(mar == 'Y' || mar == 'y') 
       printf("%s Mrs. %s.\n", str, lName); 

      else if(mar == 'n' && age >= 20|| mar == 'N' && age >= 20) 
       printf("%s Ms. %s.\n", str, lName); 
     } 

     else 
      printf("%s %s %s.\n", str, fName, lName); 
    } 

    else if(gender == 'M' || gender == 'm') 
    { 
     if(age >= 20) 
      printf("%s Mr. %s.\n", str, lName); 

     else 
      printf("%s %s %s.\n", str, fName,lName); 
    } 

    return 0; 
} 

И выход:

What is your gender (M or F): F 
First name: Jane 
Last name: Doe 
Age: 25 

Are you married, Jane (y or n)?: 

У меня также есть еще один вопрос, когда я использовал fgets вместо scanf читать строку. Как я слышал, как правило, держаться подальше от scanf при чтении строк я пробовал fgets, но результат был не таким, каким я хотел.

Вот выход, когда я использовал fgets вместо scanf:

What is your gender (M or F): M 
First name: Last name: Joe 
Age: 23 

Then I shall call you Mr. Joe. 

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

+2

Ваши проблемы возникают при смешивании одного символа 'getchar()' с вводом нескольких символов в 'scanf' или' fgets'. Когда вы нажимаете Enter, это создает и персонаж, с которым вы должны справиться. –

+1

Используйте 'scanf ("% c ", &mar);' или 'getchar(); mar = getchar()'. Проблема состоит в том, что символ новой строки остался прежним scanf. –

+1

при вызове системной функции: 'scanf() ', 1) всегда проверяйте возвращаемое значение (а не значение параметра), чтобы убедиться, что операция прошла успешно. 2) при использовании строки ввода/форматирования, которая не пропускает пробел автоматически, вставьте пробел в строку формата перед (например)% s, поэтому любое ведущее белое пространство автоматически будет потреблено. 3) при использовании формата '% s' всегда используйте модификатор максимальной длины (который должен быть на 1 меньше фактической длины входного буфера) I.E. '% 14s' для входного буфера на 15 символов. – user3629249

ответ

3

Почему не getchar() получить любой входной сигнал?

код имеет 2 проблемы:

1) он получил левый над '\n' из предыдущей строки, используйте scanf(" %c", &mar); (примечание пространства) или еще лучше, заменить все входные данные с fgets()

2) Он не сообщил о неожиданном вводе. Код должен обнаруживать и сообщать о неожиданном вводе и обрабатывать все возможные пути логики. Пример:

{ 
     printf("Are you married, %s (y or n)?: ", fName); 
     mar=getchar(); 
     printf("%c\n", mar); 
     if(mar == 'Y' || mar == 'y') 
      printf("%s Mrs. %s.\n", str, lName); 
     else if(mar == 'N' || mar == 'n') { 
      if (age >= 20) 
      printf("%s Ms. %s.\n", str, lName); 
      else 
      printf("%s ??? %s.\n", str, lName); 
     } 
     else { 
      printf("Unexpected input char:'%c' code:%d\n", mar, mar); 
     } 
    } 
+0

Я использовал 'scanf ("% c ", &mar);', но я предпочел бы использовать 'fgets' из-за его лучшей привычки, но когда я пытаюсь это сделать, он дает мне предупреждения, говоря, что его указатель от целочисленный, когда явно его бросок, есть ли способ сделать это правильно? –

+0

@Asad Mahmood «когда я пытаюсь сделать _it_» ?? _it_ неясно. – chux

+0

* когда я пытался использовать 'fgets'. –

2

Проблема scanf. Он не удаляет символ новой строки из входного буфера, поэтому первое, что читается getchar, это \n -char.

Чтобы решить эту проблему, вы можете, например, добавить вызов getchar раньше, поэтому символ удаляется из буфера, а следующий getchar читает ваши данные. Как это:

... 
scanf("%d", &age); 
... 
getchar(); 
mar = getchar(); 
... 
+3

или, может быть, он должен просто прекратить использование 'scanf()' вместо того, чтобы пытаться взломать его ужасное поведение. OP хочет прочитать один фрагмент данных по строке; поэтому он должен использовать 'fgets()'. Использование 'fgets()' также безопаснее, поскольку оно устраняет ошибки переполнения буфера. –

Смежные вопросы