печать строкового аргумента char* в объект UnicodeString

Можно ли напечатать аргумент char* в объект UnicodeString через printf функция-член?

Следующий код дает мне неправильный результат (поврежденная строка):

UnicodeString s;
s.printf(L"%s", "hello");

Если я указываю L"hello" вместо "hello", он работает как положено (мне странно, почему он работает со спецификатором "%s", я думаю, что он должен быть "%ls").

Протестировано на Embarcadero RAD Studio XE и 10 Seattle путем присвоения строки s свойству Caption метки формы.


person αλεχολυτ    schedule 29.12.2015    source источник
comment
В стандартном C++ нет типа UnicodeString, поэтому вы должны использовать какую-то библиотеку расширений. Попробуйте обратиться к документации этой библиотеки. Кроме того, попробуйте %hs, который работает по крайней мере для одной реализации swprintf(), но это выстрел в темноту...   -  person Ulrich Eckhardt    schedule 29.12.2015
comment
@UlrichEckhardt %hs работает нормально. Спасибо.   -  person αλεχολυτ    schedule 29.12.2015
comment
@UlrichEckhardt, сколько вы берете за хрустальный шар?   -  person SergeyA    schedule 29.12.2015
comment
Я подозреваю, что %s - это поддержка чего-то вроде Microsoft TCHAR, где #define переключается между сборками с широкими и узкими символами. Таким образом, %ls — это широкий символ (всегда), %hs — это узкий символ (всегда), а %s — это то, что выбрал #define.   -  person Martin Bonner supports Monica    schedule 29.12.2015
comment
@MartinBonner вполне логичное утверждение, но на практике оно, к сожалению, не подтверждается.   -  person αλεχολυτ    schedule 29.12.2015


Ответы (1)


UnicodeString::printf() — это оболочка для функции vsnwprintf() в стиле C. Во всех функциях печати C++Builder в стиле C %s использует нестандартную реализацию — это зависит от того, вызывается ли узкая или широкая версия функции, тогда как в стандарте C вместо %s всегда ожидается char*.

В этом случае UnicodeString::printf() вызывает функцию Wide vsnwprintf(), поэтому %s ожидает wchar_t* (однако %ls всегда ожидает wchar_t* по стандартам C, а %hs всегда ожидает char* по стандартам Borland). Таким образом, в String::printf() (и других методах печати) %s должно соответствовать типу символа String - char* для AnsiString, wchar_t* для UnicodeString*.

* Однако на Android Embarcadero не реализовал широкий vsnwprintf(), только узкий vsnprintf(), поэтому UnicodeString::printf() (и другие методы печати) в конечном итоге ожидает UTF-8 char* для %s! (о котором я сообщил как QC #124607 и RSP-13285).

person Remy Lebeau    schedule 29.12.2015
comment
Спецификатор s не допускает модификатор h по стандарту C. Допустимы только %s (для char*) и %ls (для wchar*). См. 7.21.6.1/8 Также стандарт C (C11) не имеет vsnwprintfn), только vswprintf и vsnwprintf_s. - person αλεχολυτ; 30.12.2015