странное поведение printf () внутри цикла while - PullRequest
3 голосов
/ 04 декабря 2011

Может кто-нибудь объяснить мне, почему я вижу двойной ввод функции printf () в цикле while:

#include <ctype.h>
#include <stdio.h>

int main(){
    int x = 0;

    while ( x != 'q'){

    printf("\nEnter a letter:");

    x=getchar();
    printf("%c\n", x);
    if( isalpha(x) )
      printf( "You entered a letter of the alphabet\n" );
    if( isdigit(x) )
      printf( "You entered the digit %c\n", x);
    }   
    return 0;
}

Вывод кода в Debian Squeeze (gcc версия 4.4.5 (Debian 4.4).5-8)) это:

Enter a letter:1
1
You entered the digit 1

Enter a letter: // why is the first one appearing ???


Enter a letter:2
2
You entered the digit 2

Ответы [ 4 ]

5 голосов
/ 04 декабря 2011

Первый читает символ конца строки, который вы ввели при нажатии Enter после 1 (терминатор строки останется в буфере ввода).

Вы можете проверить это, добавив ветку else:

#include <ctype.h>
#include <stdio.h>

int main()
{
  int x = 0;
  while ( x != 'q')
  {
    printf("\nEnter a letter:");
    x = getchar();
    printf("%c\n", x);
    if( isalpha(x) )
      printf( "You entered a letter of the alphabet\n" );
    else if( isdigit(x) )
      printf( "You entered the digit %c\n", x);
    else
      printf("Neither letter, nor digit: %02X\n", x);
  }
  return 0;
}

Выход:

Enter a letter:1
1
You entered the digit 1

Enter a letter:

Neither letter, nor digit: 0A

Enter a letter:2

Байт 0A является символом перевода строки.

1 голос
/ 04 декабря 2011

Во второй раз в цикле getchar() получает Enter после первого введенного вами символа.

Вы можете сделать что-то вроде

while ((c = getchar()) != EOF && c != '\n') {} /* eat the rest of the line */

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

0 голосов
/ 04 декабря 2011

Используйте CTRL + D, чтобы получить функциональность символа новой строки без его побочного эффекта.

0 голосов
/ 04 декабря 2011

Если вы хотите проверять символы, когда вводите немного более сложную технику, вы должны изменить поведение стандартного ввода на сырой режим. Затем, как только пользователь нажмет на символ, вы получите его в своей переменной. Проверьте это для начала

...