Ваша книга не очень полезна.
1) Выходные потоки отправляют свои байты в std::streambuf
, которые могут содержать буфер; std::filebuf
(производный от streambuf
), используемый и std::ofstream
, как правило, буферизуется. Это означает, что когда вы выводите символ, он не обязательно выводится немедленно; он будет записываться в буфер и выводиться в ОС только тогда, когда буфер заполнен , или вы явно запросите его каким-то образом, как правило, путем вызова flush()
в потоке (прямо или косвенно, используя std::endl
). Это может меняться, однако; выход на std::cout
синхронизируется с stdout
, и большинство реализаций будет более или менее следовать правилам stdout
для std::cout
, изменения стратегии буферизации, если выход будет интерактивным устройством.
Во всяком случае, если вы не уверены, и вы хотите быть уверены, что выход действительно покинет вашу программу, просто добавьте вызов для очистки.
2) Ваша книга здесь не так.
Одна из стратегий буферизации - unitbuf
; это флаг в std::ostream
, который можно установить или сбросить (std::ios_base::set()
и std::ios_base::unset()
— std::ios_base
является базовым классом std::ostream
, так что вы можете вызывать эти функции на std::ostream
объекта). Когда unitbuf
установлен, std::ostream
добавляет вызов flush()
к концу каждой выходной функции, поэтому, когда вы пишете:
std::cerr << "hello, world";
поток будет очищен после всех из символов в строке выводятся , при условии, что установлено unitbuf
. При запуске unitbuf
установлено для std::cerr
; по умолчанию он не установлен ни в одном другом файле. Но вы, , можете установить или отключить его по своему усмотрению. Я бы порекомендовал против , установив его на std::cerr
, но если std::cout
выводит на интерактивное устройство , это имеет смысл установить его там.
Обратите внимание, что все, о чем идет речь, это буфер в streambuf
. Как правило, ОС также буферизуется. Вся промывка буфера составляет , перевод символов в ОС; этот факт означает, что вы не можете использовать ofstream
непосредственно, когда требуется целостность транзакции.
3) При вводе в строку или буфер символов с помощью >>
, то std::istream
первые скачет ведущие пробельные, а затем вводит до , но не включая следующее белое пространство. В формальных терминах стандарта он «извлекает» символы из потока, так что они больше не будут видны (если вы не ищете, если поток поддерживает его). Следующий вход будет срабатывать, когда бы ни было остановлено предыдущее. Будут ли следующие символы в буфере или все еще на диске, действительно неуместны.
Обратите внимание, что буферизация ввода несколько сложна, поскольку она встречается на разных уровнях, а на уровне ОС она принимает различные формы в зависимости от устройства. Как правило, ОС будет буферизовать файл на секторах, часто просматривая несколько секторов заранее. ОС всегда будет вернуть столько символов, сколько требовалось, если только не встречается конец файла . Большинство ОС буферизуют клавиатуру за строкой: не возвращаются из запроса на чтение до тех пор, пока не будет введена полная строка, и никогда не вернет символов за пределы текущей строки в запросе на чтение.
Таким же образом, как std::ostream
использует streambuf
для вывода, std::istream
использует один, чтобы получить каждый индивидуальный характер. В случае от std::cin
он обычно будет filebuf
; когда istream
запрашивает символ, filebuf
вернет его из своего буфера, если имеет один; если это не так, он попытается пополнить буфер, с запросом, например. 512 (или независимо от его размера буфера) от ОС. Который ответит в соответствии со своей политикой буферизации для устройства , как описано выше.
Во всяком случае, если std::cin
подключен к клавиатуре, и вы набрали "hello world"
, все символы, которые вы уже напечатанных будет читаться потоком в конце концов. (Но если вы используете >>
, там будет много неиспользованного что вы не увидите.)
Стандартное примечание: по умолчанию 'cout' синхронизируется с' stdio', и по умолчанию ' stdio' - буферизируется по строке. – ybungalobill
Собственно, во втором примере вы будете записывать в память в неизвестном месте и вызывать неопределенное поведение ... ** надеюсь, что ** приведет к сбою. –