2009-04-28 2 views
3

Согласно this post std :: cout автоматически закрашивается на \n, когда он подключен к интерактивному устройству (например, к терминальному окну). В противном случае (например, при передаче в файл) он будет действовать полностью буферизованным и будет только на .flush() или std::endl.Могу ли я остановить std :: cout flushing на " n"?

Есть ли способ переопределить это поведение в Microsoft Visual C++, чтобы я мог выбрать, хочу ли я полностью буферизованный или линейный буферный режим?

+0

Возможно, это может быть полезно, я сомневаюсь, что это поможет вам с вашей проблемой. http://nibuthomas.com/2009/02/12/writing-endl-like-functions-for-output-streams/ – Skurmedel

+0

Кажется, что есть некоторые дебаты относительно легитимности утверждения о том, что C++ включает в себя C90-буферизацию строк vs полностью буферизованное различие для std :: cout. Независимо от того, есть ли способ изменить режим буферизации с помощью MSVC? – pauldoo

+0

Возможно, вы могли бы написать тестовую программу и посмотреть, верно ли утверждение? – Skurmedel

ответ

1

Это не проблема с C++ (нет языкового требования, которое \ n сбрасывает что-либо), но с вашей операционной системой и/или консольным программным обеспечением. Если консоль хочет сбросить свой буфер, когда увидит новую строку, тогда он может, и я бы предположил, что большинство из них это делает. Обратите внимание, что важно различать буферы времени выполнения C++ (которые в некоторой степени контролируются вашим кодом на C++) и буферами консольного приложения (по которым он не контролирует).

FYI, есть флаг в стандартной библиотеке iostream под названием unitbuf, который, если установлен, вызывает сброс буферов после каждой операции вывода. Он устанавливается, например, для потока std :: cerr. Однако это не имеет ничего общего с символом «\ n», поскольку вы можете вывести несколько «\ n» за одну операцию.

+0

Со страницы, с которой я связан: «Если стандартный вывод подключен или может быть присоединен к интерактивному устройству, он буферизируется по строке, иначе он полностью буферизуется.(C99 указывает это в разделе 7.19.3, пункт 7, я считаю, что C90 говорит то же самое, а C++ 98 включает C90 по ссылке.) «Вы считаете, что это неправильно? – pauldoo

+2

У меня нет доступа к стандарту C документы, поэтому не могут комментировать. Однако стандарт C++ НЕ включает стандарт C, по ссылке или иным образом. Стандарт C++ относится к стандарту C. В конкретных случаях – 2009-04-28 11:07:35

+0

@pauldoo: Я слышал, что утверждение о C++ включая C до, но, насколько я знаю, это относится только к конкретным разделам. У вас есть источник для этого? – jalf

0

Реализация бесплатна для очистки, когда это кажется уместным. Он варьируется от поставщика к поставщику независимо от того, установлены ли они на \n или нет.

Я вижу что-то под названием ios_base& nounitbuf(ios_base& str); из моего проекта C++ 0x. Дать ему шанс. Это единственное, что дает вам стандартный C++.

+0

nonunitbuf похоже, не находится в текущем стандарте – 2009-04-28 09:03:56

+0

Хм, я не был уверен, поэтому я упомянул проект. – dirkgently

+0

Однако добросовестные исследования показывают, что есть флаг потока «unitbuf», устанавливающий это sh После каждой операции очистите поток. Я обновлю свой ответ, чтобы отразить это. – 2009-04-28 11:21:30

7

В отличие от ответа анонса (28 апреля 2009 г.) это поведение не имеет ничего общего с операционной системой или «консольным программным обеспечением».

Потоки C++ <iostream> предназначены для взаимодействия с потоками C <stdio.h>. Цель состоит в том, чтобы разрешить использование std::cout с использованием printf/puts. Чтобы достичь этого, std::coutstreambuf реализован на потоке stdout C. На самом деле это C stdout, который буферизируется по строке, когда стандартный вывод подключен к терминальному устройству.

Вы можете позвонить std::ios_base::sync_with_stdio(false) (прежде чем ваша программа будет использовать любые стандартные потоки ввода-вывода C++), чтобы сообщить библиотеке потоков C++ напрямую связываться с файловыми дескрипторами, а не располагать поверх библиотеки потоков C. Это полностью исключает поток stdout C и ускоряет потоки ввода-вывода C++ за счет того, что две библиотеки больше не смешиваются.

Альтернативой является безоговорочно установить stdout для полного буферирования путем вызова std::setvbuf(stdout, nullptr, _IOFBF, BUFSIZ). Затем, хотя std::cout все еще пишет через stdout, у вас не будет stdout промывки после каждой новой строки.

Смежные вопросы