Я не могу очистить стандартный ввод

Как очистить стандартный ввод??

Почему это не работает в следующем фрагменте кода?

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

int main()
{
        int i=0,j=0, sat;
        char arg[256];
        char * argq;
        argq = malloc(sizeof(char)*10);

        printf("Input the line\n");
        i=read(0, arg, sizeof(char)*9);
        arg[i-1]='\0';
        fflush(stdin);

        i=read(0, argq, sizeof(char)*5);
        argq[i-1]='\0';

        puts(arg);
        puts(argq);

        return 0;
}

Теперь, если я ввожу ввод как 11 символов, следует прочитать только 9, но оставшиеся два символа в стандартном вводе не сбрасываются и снова считываются в argq. Почему?

Ввод: 123 456 789

Выход: 123 456 89

Почему я получаю это 89 в качестве вывода?


person Subodh Asthana    schedule 02.02.2010    source источник
comment
Потому что fflush() определен только для выходных потоков.   -  person    schedule 02.02.2010
comment
Вы всегда можете создать свою функцию для отбрасывания вводимых символов. Если вы назовете его ignore, то вы можете быть ближе к потокам C++. ;-)   -  person Thomas Matthews    schedule 03.02.2010


Ответы (7)


Я считаю, что fflush используется только с выходными потоками.

Вы можете попробовать fpurge или __fpurge в Linux. Обратите внимание, что fpurge не является стандартным и не переносимым. Он может быть недоступен для вас.

Из справочной страницы Linux fpurge: обычно отказ от входных буферов является ошибкой.

Наиболее переносимым решением для сброса стандартного ввода, вероятно, будет что-то вроде следующего:

int c;
while ((c = getchar()) != '\n' && c != EOF);
person jschmier    schedule 02.02.2010
comment
Хорошо - не знал о fpurge() - person mob; 02.02.2010
comment
Или, проще: scanf("%*[^\n]%*c"); Вы, конечно, можете объединить это в конец существующей строки формата scanf, чтобы отбросить оставшуюся часть строки после обработки ее части также с помощью scanf. - person R.. GitHub STOP HELPING ICE; 28.11.2012
comment
@R .. возможно, вы могли бы объяснить предоставленное регулярное выражение более подробно, хотя прошло уже 5 лет. Или дайте ссылку на материал, который может пояснить это. - person Ungeheuer; 05.04.2017
comment
@Ungeheuer: это не регулярное выражение. Это спецификатор преобразования scanf %[, который должен быть задокументирован с помощью scanf. - person R.. GitHub STOP HELPING ICE; 06.04.2017


int c;
while((c = getchar()) != '\n' && c != EOF);

Как бы я очистил входной буфер.

person Community    schedule 27.01.2012
comment
В этом случае может быть потенциальный недостаток. Скажем, после этого вы хотите использовать fgets для чтения из stdin, который пуст, тогда вам нужно сначала ввести ключ enter перед фактическим вводом. - person J.G; 26.03.2019

Как сбросить стандартный ввод??

Сброс входных потоков вызывает неопределенное поведение. Не пытайтесь.

Вы можете сбрасывать только потоки вывода.

person dirkgently    schedule 02.02.2010

Вы переопределяете последний элемент ввода в arg с помощью '\0'. Вместо этого эта строка должна быть arg[i]='\0'; (после проверки ошибок и границ вы пропали без вести.)

Другие уже прокомментировали промывочную часть.

person Nikolai Fetissov    schedule 02.02.2010

Вы не можете очистить стандартный ввод в Linux, не сталкиваясь со сценариями, когда команда в некоторых случаях начнет ожидать ввода. Способ решить эту проблему — заменить все std::cin на readLineToStdString():

void readLine(char* input , int nMaxLenIncludingTerminatingNull )
{
    fgets(input, nMaxLenIncludingTerminatingNull , stdin);

    int nLen = strlen(input);

    if ( input[nLen-1] == '\n' )
        input[nLen-1] = '\0';
}

std::string readLineToStdString(int nMaxLenIncludingTerminatingNull)
{
    if ( nMaxLenIncludingTerminatingNull <= 0 )
        return "";

    char* input = new char[nMaxLenIncludingTerminatingNull];
    readLine(input , nMaxLenIncludingTerminatingNull );

    string sResult = input;

    delete[] input;
    input = NULL;

    return sResult;
}

Это также позволит вам вводить пробелы в строку std::cin.

person Sunny127    schedule 24.12.2017

В Windows вы можете использовать функцию rewind(stdin).

person Ngô Thái Sơn    schedule 03.06.2016
comment
почему бы вам не опубликовать проверенный фрагмент кода вместе со своим кодом. Потому что перемотка не предназначена для того, чего хочет добиться OP. - person HaseeB Mir; 27.11.2018