0

Is it possible to print char* argument into UnicodeString object via printf member function?

Following code gives me a wrong result (damaged string):

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

If I specify L"hello" instead of "hello" it works as expected (strange to me, why it works with "%s" specifier, i think it should be "%ls").

Tested on Embarcadero RAD Studio XE and 10 Seattle by assigning s string to Caption property of the form's Label.

5
  • 3
    There is no UnicodeString type in standard C++, so you must be using some extension library. Try consulting that lib's documentation. Also, try %hs, which works for at least one swprintf() implementation, but that's a shot in the dark... Commented Dec 29, 2015 at 14:40
  • @UlrichEckhardt %hs works fine. Thanks. Commented Dec 29, 2015 at 14:42
  • 1
    @UlrichEckhardt, how much do you charge for the crystall ball? Commented Dec 29, 2015 at 14:58
  • I suspect the "%s" thing is support for something like Microsofts TCHAR where a #define switches between wide-char and narrow-char builds. So "%ls" is wide char (always), "%hs" is narrow char (always), and "%s" is "whatever the #define has selected". Commented Dec 29, 2015 at 15:14
  • 1
    @MartinBonner it is quite logical statement, but in practice it does not confirm, unfortunately. Commented Dec 29, 2015 at 15:25

1 Answer 1

2

UnicodeString::printf() is a wrapper for the C-style vsnwprintf() function. In all of C++Builder's C-style printing functions, %s uses a non-standard implementation - it depends on whether the Narrow or Wide version of the function is being called, whereas in the C standard, %s always expects char* instead.

In this case, UnicodeString::printf() calls the Wide vsnwprintf() function, so %s expects a wchar_t* (however, %ls always expects a wchar_t*, per C standards, and %hs always expects a char*, per Borland standards). This way, in String::printf() (and other printing methods), %s is supposed to match the character type of String - char* for AnsiString, wchar_t* for UnicodeString*.

*However, on Android, Embarcadero has not implemented the Wide vsnwprintf(), only the Narrow vsnprintf(), so UnicodeString::printf() (and other printing methods) end up expecting a UTF-8 char* for %s! (which I reported as QC #124607 and RSP-13285).

Sign up to request clarification or add additional context in comments.

1 Comment

s specifier does not allow h modifier by C standard. Only %s (for char*) and %ls (for wchar*) are legal. See 7.21.6.1/8 Also C standard (C11) does not has vsnwprintf (with n), only vswprintf and vsnwprintf_s.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.