В чем разница между printf (& quot;% s & quot;), printf (& quot;% ls & quot;), wprintf (& quot;% s & quot;) и wprintf (& quot;% ls & quot;)?

Рассмотрим этот пример программы:

#include <cstdio>
#include <cwchar>
#include <string>

int main()
{
std::string narrowstr = "narrow";
std::wstring widestr = L"wide";
printf("1 %s \n", narrowstr.c_str());
printf("2 %ls \n", widestr.c_str());
wprintf(L"3 %s \n", narrowstr.c_str());
wprintf(L"4 %ls \n", widestr.c_str());

return 0;
}

Выход этого:

1 narrow
2 wide

Я задаюсь вопросом:

  1. почему 3 & 4 не печатал
  2. какие различия между 1&3 и 2&4.
  3. Имеет ли какое-либо значение, если в поле utf8 есть узкий, а в utf16 — самый широкий?

14

Решение

Вам нужно сделать:

wprintf(L"3 %hs \n", narrowstr.c_str());
wprintf(L"4 %s \n", widestr.c_str());

Зачем? Потому что для printf, % s говорит узкий символ За wprintf, % Ls говорит широкий.

Но для wprintf, % s подразумевает широкий, % Ls будет означать сам по себе. % вс будет означать узкий (для обоих). За printf, % s, таким образом, будет просто означать % вс

На VC ++ / Windows, %S (заглавная S), обратный эффект. Therfore для printf("%S") это будет означать широкий и wprintf("%S") будет означать узкий Это полезно для _tprintf,

8

Другие решения

Обратите внимание, что вы используете C-потоки. C потоки имеют очень особое качество, называемое «ориентация». Поток либо неориентирован, либо широк, либо узок. Ориентация определяется первым выводом, сделанным для любого конкретного потока (см. http://en.cppreference.com/w/cpp/io/c для сводки потоков ввода / вывода C)

В твоем случае, stdout начинается неориентированным, и выполняя первый printfВы устанавливаете это узко. Однажды узкий, он застрял узкий, и wprintf не удается (проверьте его код возврата!). Единственный способ изменить поток C — это freopen это, которое не совсем работает с stdout. Вот почему 3 и 4 не печатали.

Разница между 1 и 3 состоит в том, что 1 — это узкая выходная функция, которая использует спецификатор преобразования узкой строки% s: она читает байты из массива char и отправляет байты в поток байтов. 3 — это широкая функция вывода с узким спецификатором преобразования строки% s: сначала она читает байты из массива char и mbtowcс ними в wchar_tс, затем отправляет wchar_tв широкий поток, который затем wctombих в байты или многобайтовые последовательности, которые затем вставляются в стандарт с write

Наконец, если widestr находится в utf16, вы должны использовать Windows, и все ставки отключены; на этой платформе очень мало поддержки, кроме ASCII. Вы можете также сдаться и использовать WinAPI (вы можете обойтись со стандартным C ++ 11 для некоторых вещей в Юникоде и даже сделать этот вывод на C, используя магические слова _setmode(_fileno(stdout), _O_U16TEXT);Обсуждали достаточно раз)

5

Ответы на 1 и 2 в вопросе находятся в документации. Подойдет любой хороший набор документации. Они говорят cppreference очень хорошо.

Что касается 3, языковой стандарт не определяет какую-либо конкретную кодировку для строк или какой-либо конкретный размер wchar_t, Вы должны обратиться к документации для вашей реализации, а не для самого языка (хотя написание кода, зависящего от реализации, редко рекомендуется).

0
По вопросам рекламы [email protected]