Подтвердить что ты не робот

Смешивание cout и wcout в одной программе

Я читал "Поваренную книгу C++", в которой был следующий фрагмент:

// cout  << s  << std::endl;  // You shouldn't be able to
wcout << ws << std::endl;     // run these at the same time

Если вам интересно посмотреть реальный пример, вот ссылка на страницу в книгах Google.

Кроме того, я нашел этот ТАК вопрос, в котором, похоже, говорится, что смешивать wcout и cout можно. Может ли кто-нибудь объяснить мне, о чем идет речь в этом комментарии?

EDIT

Из C++ стандарта [27.4.1]:

Операции микширования в соответствующих wide- и узкополосных потоках следуют той же семантике, что и операции микширования в файлах FILE, как указано в поправке 1 к стандарту ISO C.

Из стандарта C [7.19.2]:

Каждый поток имеет ориентацию. После того, как поток связан с внешним файлом, но перед выполнением каких-либо операций над ним поток не имеет ориентации. Однажды широкий функция ввода/вывода символов была применена к потоку без ориентации, поток становится ориентированным потоком wide-. Аналогично, когда байтовая функция ввода/вывода имеет Применительно к потоку без ориентации поток становится байтово-ориентированным потоком. В противном случае только вызов функции freopen или функции fwide может изменить ориентация потока. (Успешный вызов freopen удаляет любую ориентацию.)

Байтовые функции ввода/вывода не должны применяться к ориентированному потоку wide- и широкому символьные функции ввода/вывода не должны применяться к байтовому потоку.

Таким образом, стандарт, кажется, говорит, что вы не должны смешивать их. Однако я нашел эту цитату из этой статьи:

Для Visual C++ 10.0 функция fwide задокументирована как невыполненная. И с практической точки зрения, по крайней мере на уровне вывода целых строк, он, очевидно, прекрасно работает, чтобы смешать использование cout и wcout. Поэтому, к счастью, Visual C++, очевидно, просто игнорирует требования стандартов и не поддерживает непрактичную явную ориентацию потока C FILE.

А также, что касается GCC, я нашел эту цитату из здесь:

Это (новая) функция, а не ошибка, см. Libstd C++/11705 и в общем поиске об ориентации потока в стандарте C (C99, 7.19.2). В двух словах ты не может смешивать байтово-ориентированный и широко-ориентированный ввод-вывод. На данный момент, из-за ошибки Как указано в libstd C++/11705, вы можете получить что-то близкое к вашему ожидания путем вызова std::ios :: sync_with_stdio (false); в начале ваша программа.

4b9b3361

Ответ 1

Когда cout или wcout вызывается в первый раз, ориентация для stdout устанавливается. В случае cout, stdout становится байтовым потоком, а в случае wcout, stdout становится широко ориентированным потоком. В соответствии со стандартом C++ [27.4.1] и стандартом C [7.19.2] после установки ориентации потока не следует вызывать функцию, несовместимую с ориентацией этого потока.

Ответ 2

Я понятия не имею.

Запрет потоков, вы не можете запускать любые два оператора "одновременно". Конечно, вы можете использовать cout и wcout в разных точках вашей программы. Они оба сопоставляются с STDOUT и что это... хотя в некоторых случаях вы можете ошибаться в разных буферах и получать слегка неожиданный порядок.

По-видимому, каждый из них накладывает ориентацию на поток "назначения" STDOUT, и ему не разрешается смешивать операции над потоком, который был пропитан ориентацией [C++11: 27.4.1] и [C99: 7.19.2].

Ответ 3

Технически вы можете определенно использовать как узкие, так и широкие потоки одновременно. Однако результат, скорее всего, будет испорчен, если вы не согласитесь, чтобы оба они кодировали символы одинаково. К сожалению, это связано с тем, что вы не можете управлять кодировками, используемыми стандартными объектами потока, по крайней мере, не переносимыми. Даже если кодировка одинакова, вам нужно убедиться, что частичные символы полностью записаны, то есть по крайней мере вам нужно сбросить буфер при переключении на другую ширину.

Ответ 4

Нарушение "не означает, что стандарт не означает, что вы находитесь в сфере поведения undefined. undefined поведение может очень хорошо работать на некоторых реализациях.

Ответ 5

Как можно предположить: cout и wcout - это два разных потока, а предоставленные вами цитаты не говорят о том, как ориентация потоков коррелирует с базовой ориентацией файла. Может быть, потоки тихо переориентируются stdout под капот?