C getchar vs scanf
Я смущен частью кода, найденной в функции, которую я изучаю:
char GetCommand( void )
{
char command;
do {
printf( "Enter command (q=quit, n=new, l=list): " );
scanf( "%c", &command );
Flush();
}
while ( (command != 'q') && (command != 'n')
&& (command != 'l') );
printf( "\n----------\n" );
return( command );
}
void Flush( void ) {
while ( getchar() != '\n' )
;
}
Что я не совсем понимаю, здесь это использование Flush()
функция. Я имею в виду, что книга, которую я читаю, объясняет это тем, что она запрещает пользователю вводить более одного символа, а затем читает этот символ, когда ему предлагается ввести данные во второй раз.
Что я не понимаю, так это как Flush()
предотвращает это Это ничего не делает. Все это while
команда. (Хотя это правда...... что?????) Не имеет смысла.
3 ответа
getchar()
имеет побочный эффект удаления следующего символа из входного буфера. Цикл в Flush
читает и сбрасывает символы до - и включая - перевод строки \n
окончание строки
Так как scanf
сказано читать один и только один символ (%c
) это приводит к игнорированию всего остального в этой строке ввода.
Вероятно, было бы более понятно, если бы scanf был заменен на
command = getchar();
но это на самом деле плохой пример, так как он плохо обрабатывает End Of File.
В общем scanf
лучше всего забыто; fgets
а также sscanf
работать намного лучше, так как один отвечает за получение входных данных, а другой - за их анализ. scanf
(а также fscanf
) попробуйте сделать слишком много работы одновременно.
getchar
читает один символ из стандартного ввода. Если вы положите его в while
Цикл, он будет продолжать читать по одному символу за раз, пока условие не станет ложным.
Что за Flush
функция читает, пока не встретит новую строку (\n
). Этот символ создается, когда пользователь нажимает клавишу ввода.
Итак, код, который вы дали, будет читать один символ (мне неясно, почему он использует scanf
для этого, а не просто getchar
(что было бы быстрее), а затем отбрасывает оставшуюся часть ввода, пока пользователь не нажмет ввод.
Если бы вы были, чтобы кормить эту программу foobar
, это займет f
и отказаться от oobar
в Flush
функция. Без звонка flush
, f
может пойти к одному scanf
и второй scanf
получил бы первый o
,
Когда вы вводите свой символ и нажимаете Enter, вы генерируете символ новой строки, нажимая клавишу Enter, и он остается в буфере. Это проблематично, потому что он будет ждать до следующего раза, когда вам потребуется ввод данных пользователем, и будет использоваться для этого ввода. Flush используется для очистки символа новой строки из входного буфера, чтобы у вас не было этой проблемы. Flush фактически использует символ новой строки во входном буфере, когда он читает его и отбрасывает, поэтому он больше не находится в буфере.