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

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

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

#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 должны быть прочитаны, но оставшиеся два символа в stdin не сбрасываются и снова считываются в argq. Зачем?

Вход: 123 456 789

Выход: 123 456 89

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

8 ответов

Решение

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

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

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

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

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

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

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

Очистка входных потоков вызывает неопределенное поведение. Не пытайся.

Вы можете очищать только выходные потоки.

Если вы используете GLIBC, вы можете просто возиться с stdin ptr вручную

      void flush_stdin(){
    unsigned long* tmpstdin = (unsigned long*)stdin;
    unsigned long* oldbuf = (unsigned long*)*(tmpstdin+4);
    free((void*)oldbuf);
    *tmpstdin=(unsigned long)0xfbad2088;
    tmpstdin+=1;
    memset(tmpstdin,'\x00',64);
}

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

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

Вы не можете очистить stdin в 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.

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

Другие вопросы по тегам