2012-01-13 3 views
9

я пишу консольное приложение, которое выполняет несколько зсапа для Int И после этого, я выполняю GetChar:чтение символ из консоли

int x,y; 
char c; 
printf("x:\n"); 
scanf("%d",&x); 
printf("y:\n"); 
scanf("%d",&y); 
c = getchar(); 

в результате этого я получаю c = '\n', несмотря на входе:

1 
2 
a 

Как решить эту проблему?

+4

'getchar()' возвращает 'int', а не' char'. – unwind

+0

@unwind - «Возвращает следующий символ из стандартного ввода (stdin)». - ascii для char – Yakov

ответ

12

Это связано с тем, что scanf оставляет введенную вами строку новой строки во входном потоке. Попробуйте

do 
    c = getchar(); 
while (isspace(c)); 

вместо

c = getchar(); 
1

Для запуска в scanf следует читать scanf("%d\n", &x); или у. Это должно делать свое дело.

man scanf

+0

Это не работает: после ввода 1 он не пишет «y:» (см. Обновленный пример), но ждет второго номера и только после того, как он пишет «y:» – Yakov

1

Вызов fflush(stdin); после того, как scanf отказаться от любых ненужных символов (например, \ г \ п) из входного буфера, которые были оставленной scanf.

Редактировать: Как ребята в упомянутых комментариях fflush решение может иметь проблему переносимости, так что вот мое второе предложение. Не используйте scanf и выполняйте эту работу, используя комбинацию fgets и sscanf. Это гораздо более безопасный и простой подход, поскольку позволяет обрабатывать неправильные исходные ситуации.

int x,y; 
char c; 
char buffer[80]; 

printf("x:\n"); 
if (NULL == fgets(buffer, 80, stdin) || 1 != sscanf(buffer, "%d", &x)) 
{ 
    printf("wrong input"); 
} 
printf("y:\n"); 
if (NULL == fgets(buffer, 80, stdin) || 1 != sscanf(buffer, "%d", &y)) 
{ 
    printf("wrong input"); 
} 
c = getchar(); 
+0

-1 'fflush (stdin)' не определен. Даже [Microsoft/MSDN] (http://msdn.microsoft.com/en-us/library/9yky46tz%28v=vs.71%29.aspx) (который определяет такую ​​конструкцию) говорит (хотя и в скрытом месте) это расширение: «// fflush на входном потоке является расширением стандарта C». – pmg

+0

@pmg: Истинный! (Даже я склонен указывать его время от времени). Это немного похоже на SO., Но оно работает * MSDN поддерживает (вы связали страницу), а также [Linux] (http://linux.die.net/man/3/fflush) ... '" Для входных потоков fflush() отбрасывает любые буферизованные данные, которые были извлечены из основного файла, но не были использованы приложением ... Стандарты не определяют поведение для входных потоков. Большинство других реализаций ведут себя одинаково как Linux ».« ... так насколько плохо это использовать в коде? –

+0

Текст на странице [POSIX.1-2008] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html) несколько отличается: он вообще не упоминает приложение. Мне вообще не нравится это описание POSIX.1-2008. Linux и Windows и POSIX (со всеми предостережениями) недостаточно для того, чтобы я мог назвать портативный. – pmg

2

Способ очистить anyspace до Вашего желаемого полукокса и просто игнорировать оставшиеся символы в

do { 
    c = getchar(); 
} while (isspace(opcao)); 
while (getchar() != '\n'); 
2

Вы можете использовать функцию fflush, чтобы очистить все, оставшиеся в буфере как consquence предыдущего COMAND линии Входы:

fflush(stdin); 
+2

'fflush (stdin)' вызывает Undefined Behavior в соответствии со стандартом C, хотя он хорошо определен в некоторых системах (реализациях), но лучше избегать его, чтобы улучшить переносимость. –

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