2010-01-23 6 views
14

stdout буферизируется по строке при подключении к терминалу, но я помню, где-то читал, что чтение (по крайней мере, из stdin) автоматически запустит stdout. Все реализации C, которые я использовал, сделали это, но теперь я не могу найти его в стандарте.Есть ли чтение из stdin flush stdout?

Это имеет смысл, что он работает именно так, иначе такой код:

printf("Type some input: "); 
fgets(line, sizeof line, stdin); 

нужно будет дополнительно fflush(stdout);

Так как стандартный вывод гарантированно промывать здесь?

EDIT:

Как несколько ответов сказал, кажется, нет гарантии в стандарте, что выход на стандартный вывод в моем примере будет появляться перед чтением из стандартного ввода, но с другой стороны , это намерение указано в (свободный черновом) стандарта:

входные и выходные динамика интерактивных устройств должны проходить , как указано в 7.19.3. Для целей эти требования заключаются в том, что небуферизованный или строковый буферизированный выход появляются как можно скорее , чтобы сообщения, которые действительно отображались до появления программы , ожидали ввода.

(ISO/IEC 9899: Проект Комитета TC2 - 6 мая 2005 г., стр. 14).

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

+1

. Перекрестная ссылка на 7.19.3 (7.21.3 на C11) также полезна, поскольку в ней упоминается, какие операции ввода, как ожидается, вызовут промывку. Они обсуждаются на https://stackoverflow.com/a/39536803/8586227. –

ответ

4

Нет, это не так.

+0

Но в целом то, что мы видим, это то, что stdout покраснели до линии fgets. Итак, почему он покраснел здесь. –

+0

Кажется, что реализация C _allowed_ стандартным образом не выводит запрос перед fgets, но «интенсией» является то, что он должен, и я думаю, что большинство (все?) Реализации. –

+0

Следуя этому намерению, все вход будет намного медленнее и для сомнительной выгоды. –

4

Нет. Необходимо выполнить fflush (stdout); Многие реализации будут очищаться при каждой новой строке, когда они отправляют вывод на терминал.

+0

AFIAK 'stdout' требуется по умолчанию для буферизации или буферизации по умолчанию. – ybungalobill

5

Чтобы ответить на ваш вопрос, вы сделать нужны дополнительные fflush(stdout); после printf() вызова, чтобы убедиться, появляется подсказка, прежде чем ваша программа пытается читать ввод. Чтение с stdin не fflush(stdout); для вас.

4

№ stdin/stdout буферизированы. Для того, чтобы буферизованные данные в памяти видеопамяти/unix-терминала были вытолкнуты на устройство просмотра, например терминал, вам необходимо объяснить fflush(stdout). Буферизацию данных можно установить, позвонив по номеру setvbuf.

Редактировать: Спасибо Jonathan, чтобы ответить на вопрос, чтение с stdin не сбрасывает stdout. Возможно, я отклонил тангенс, указав код, демонстрирующий, как использовать setvbuf.

 
    #include 

    int main(void) 
    { 
    FILE *input, *output; 
    char bufr[512]; 

    input = fopen("file.in", "r+b"); 
    output = fopen("file.out", "w"); 

    /* set up input stream for minimal disk access, 
     using our own character buffer */ 
    if (setvbuf(input, bufr, _IOFBF, 512) != 0) 
     printf("failed to set up buffer for input file\n"); 
    else 
     printf("buffer set up for input file\n"); 

    /* set up output stream for line buffering using space that 
     will be obtained through an indirect call to malloc */ 
    if (setvbuf(output, NULL, _IOLBF, 132) != 0) 
     printf("failed to set up buffer for output file\n"); 
    else 
     printf("buffer set up for output file\n"); 

    /* perform file I/O here */ 

    /* close files */ 
    fclose(input); 
    fclose(output); 
    return 0; 
    } 

Надеется, что это помогает, С наилучшими пожеланиями, Том.

+0

Как ваш код относится к поведению stdin и stdout? –

+0

@ Джонатан: Это пример того, как установить буфер для ввода, используя setvbuf, равный 512, или любую цифру, если это важно, предпочтительно на границе слова. Это был образец, взятый из файла справки в компиляторе Borland C, в котором показано использование setvbuf. – t0mm13b

+0

Код в порядке как ответ на другой вопрос - он не затрагивает заданный вопрос, который «делает чтение из stdin flush stdout». Я не собираюсь наказывать вас за тангенциальный ответ, но я считаю ваш ответ тангенциальным. –

2

Нет, это не стандарт.Конечно, возможно, что вы использовали реализацию библиотеки, где описанное вами поведение произошло, но это нестандартное расширение, на которое вы не должны полагаться.

1

Нет. Следите за взаимоблокирующими взаимоблокировками при работе со стд-потоками при чтении на stdin или записи на блоках stdout.