Следующие строки обе «работают как задумано»:
wchar_t u[50], v[50];
swprintf(u, 50, L"%s", L"hello");
swprintf(v, 50, L"%ls", L"goodbye");
MessageBoxW(NULL, u, v, MB_OK); // output: MessageBox showing "hello" and "goodbye"
Есть ли способ напечатать узкую строку, и где документация для этого? Например.
swprintf(u, 50, L"%?", "hello");
Стандарт C ++ указывает (посредством ссылки на стандарт C), что в wprintf
семейство функций, %s
указывает строку char
(в многобайтовом кодировании, например, UTF-8), и %ls
указывает строку wchar_t
,
Таким образом, RTL (реализация библиотеки времени выполнения, поставляемая с C ++ Builder), очевидно, здесь не соответствует стандартам.
Справочная информация: я на самом деле пытаюсь использовать UnicodeString::sprintf
Однако, что делегирует тяжелую работу vswprintf
,
Это на самом деле не ответ, а скорее подборка элементов.
Сайт http://www.cplusplus.com/ ясно: для wprintf
семья: … все спецификаторы формата имеют то же значение, что и в printf; следовательно,% lc должен использоваться для записи широких символов (а не% c), а также% ls должен использоваться для широких строк (а не% s)
gcc и clang оба соответствуют вышеуказанной спецификации
MSVC и в соответствии с OP Borland C ++ не соответствуют и не принимают %s
для широкой струны.
Мне удалось найти это в vprinter.c
файл в исходном коде RTL (C ++ Builder поставляется со своим собственным RTL, он не ссылается на MS):
/* The 's' conversion takes a string (char *) as
* argument and copies the string to the output
* buffer.
*
* Note: We must handle both narrow and wide versions
* depending on the flags specified and the version called:
*
* Format printf wprintf
* ----------------------------------------
* %s narrow wide
* %S wide narrow
* %hs narrow narrow
* %hS narrow narrow
* %ls wide wide
* %lS wide wide
*
*/
Итак, код:
swprintf(v, 50, L"%hs", "hello");
генерирует правильный вывод.
Однако это не делает никакого преобразования UTF-8; узкие символы «расширяются» путем добавления нулевого байта. (Подтверждено проверкой исхода источника).