C getchar vs scanf - PullRequest
       19

C getchar vs scanf

11 голосов
/ 04 сентября 2010

Меня смущает фрагмент кода, найденный в функции, которую я изучаю:

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 ]

10 голосов
/ 04 сентября 2010

getchar() имеет побочный эффект удаления следующего символа из входного буфера.Цикл в Flush читает и отбрасывает символы до - и включая - новую строку \n, заканчивающую строку.

Так как scanf велит читать один и только один символ (%c), этоимеет эффект игнорирования всего остального в этой строке ввода.

Вероятно, было бы более понятно, если бы scanf был заменен на

command = getchar();

, но на самом деле это, как правило, плохой пример, посколькухорошо разбирайтесь в End Of File.

В общем scanf лучше всего забыть;fgets и sscanf работают намного лучше, так как один отвечает за получение ввода, а другой - за его анализ.scanffscanf) пытаются выполнять слишком много заданий одновременно.

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

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

Функция Flush выполняет чтение до тех пор, пока не встретит символ новой строки (\n).Это символ, который появляется, когда пользователь нажимает клавишу ввода.

Итак, код, который вы дали, будет читать один символ (мне неясно, почему он использует для этого scanf вместо простого getchar,что будет быстрее), а затем отбрасывает оставшуюся часть ввода до тех пор, пока пользователь не нажмет клавишу ввода.

Если бы вы кормили эту программу foobar, она бы взяла f и отбросила oobarв функции Flush.Без вызова flush, f может перейти к одному scanf, а второй scanf получит первый o.

0 голосов
/ 03 декабря 2018

Когда вы вводите свой символ и нажимаете Enter, вы генерируете символ новой строки, нажимая клавишу Enter, и он остается в буфере. Это проблематично, потому что он будет ждать до следующего раза, когда вам потребуется ввод данных пользователем, и будет использоваться для этого ввода. Flush используется для очистки символа новой строки из входного буфера, чтобы у вас не было этой проблемы. Flush фактически использует символ новой строки во входном буфере, когда он читает его и отбрасывает, поэтому он больше не находится в буфере.

...