Using String::formatted with %s?


Juce newbie here. I’ve recently started working on some Juce-based code, and am getting my head wrapped around the Juce way of doing things. I was taking a look at some code for logging some system info to a file, which worked fine on Windows, but not on the Mac. Turns out there was a bunch of code similar to this (simplified):

String test("TEST"); pLogStream->writeText(String::formatted(T("This is a %s\n"), (const tchar*)test), false, false);

After looking into this a bit, it seems to me that this just shouldn’t work in the case where JUCE_STRINGS_ARE_UNICODE is set to 1 (which is the case for us, for both Mac and Win projects). String::formatted() ends up eventually calling CharacterFunctions::vprintf(), which calls _vsnwprintf on Win or vswprintf otherwise. Looking at the docs for that it seems to me that any strings passed in for %s substitution should be regular character strings (not wide). Sure enough, if I change the code to pass in a regular character string, it works on the Mac. But that breaks on Win. I can also use %ls and pass in a wide string, and that works… but not if we decide to change JUCE_STRINGS_ARE_UNICODE!

So I guess I’m wondering if there’s a standard way to pass strings as varargs to String::formatted() that will work regardless of the setting of JUCE_STRINGS_ARE_UNICODE?

My workaround now is to just manually concatenate the strings via the String class, i.e.:

String test("TEST"); pLogStream->writeText(String(T("This is a ")) + test + String(T("\n")), false, false);


Yes, I’d probably avoid %s if I were you, as it is highly platform-specific. I’d recommend just building your strings out of << operators unless you’re just using primitive integer or float values.

(I should probably add a note about this to the docs…)