На этом шаге мы рассмотрим проблемы синхроизации со стандартными потоками данных C.
По умолчанию восемь стандартных потоков данных C++ (четыре символьных потока с однобайтовой кодировкой cin, cout, cerr и clog,
а также четыре их аналога с расширенной кодировкой) синхронизируются с соответствующими каналами из стандартной библиотеки С
(stdin, stdout и stderr). По умолчанию clog и wclog используют тот же потоковый буфер, что и cerr и wcerr
соответственно. Таким образом, по умолчанию они синхронизируются с stderr, хотя в стандартной библиотеке С у этих потоков
данных нет прямых аналогов.
В зависимости от реализации синхронизация может приводить к лишним затратам. Например, если стандартные потоки данных C++ реализованы
с использованием стандартных файлов С, это фактически подавляет буферизацию соответствующих потоковых буферов. Однако буферизация
необходима для выполнения некоторых оптимизаций, особенно для форматированного чтения. Чтобы программист мог переключиться на нужную
реализацию, в классе ios_base определена статическая функция sync_with_stdio() (таблица 1).
Таблица 1. Синхронизация стандартных потоков данных C++ и С
Статическая функция | Описание |
---|---|
sync_with_stdio() | Возвращает информацию о том, синхронизируются ли стандартные объекты потоков данных со стандартными потоками данных С |
sync_with_stdio(false) | Запрещает синхронизацию потоков данных C++ и С (при условии, что функция была вызвана до первой операции ввода-вывода) |
При вызове функции sync_with_stdio() передается необязательный логический аргумент, который указывает, нужно ли активизировать синхронизацию
со стандартными потоками данных С. Для отключения синхронизации функция вызывается с аргументом false:
std::ios::sync_with_stdio(false); // Отключение синхронизации
Помните, что синхронизация отключается только до выполнения любой операции ввода-вывода. Если это условие не выполнено, последствия от
вызова функции зависят от реализации.
Функция sync_with_stdio() возвращает значение, использованное при предыдущем вызове. Если ранее функция не вызывалась, она всегда
возвращает true, отражающее состояние по умолчанию для стандартных потоков данных.
На следующем шаге мы рассмотрим буферизацию в потоковых буферах.