The following line of code gives garbage with Visual Studio 2010:
swprintf(buf, L"Value is %s", "abcd");
However, the same code works fine on Linux.
By trial, I could make it work by using %S instead of %s under Visual Studio.
swprintf(buf, L"Value is %S", "abcd");
I am wondering if this is a bug in Visual Studio 2010 or am I missing something. Regards.
The swprintf() function returns the number of wide characters that are written to the output buffer, not counting the ending null wide character or a negative value if an error is encountered. If n or more wide characters are requested to be written, a negative value is returned.
The swprintf() function in C++ is used to write a formatted wide string to a wide string buffer. The swprintf() function is defined in <cwchar> header file.
This is a "bug," though the behavior is by design. The initial Visual C++ implementation of the wide string printf and scanf functions predated their standardization in C, and in some cases the behavior deviates from what is required by the C Standard Library specification.
In the C Standard Library specification, a %s
or %c
format specifier must always be paired with a char
array or element, and the l
length modifier must be used when a wchar_t
array or element is provided.
In the Visual C++ implementation of these functions (documentation), the %s
and %c
format specifiers expect a corresponding argument of the "natural" width. For the narrow string printf and scanf functions, a char
pointer or element is required and for the wide string functions a wchar_t
pointer or element is required. To pass a string of the "other" width, the %S
and %C
format specifiers may be used. Alternatively, the h
and l
length modifiers may be used to explicitly specify that the string argument is a narrow or wide string.
Among other advantages, the Visual C++ implementation of these functions made it possible to easily migrate old code to use Unicode strings via the _TCHAR
mappings in <tchar.h>
. It is unfortunate that what was standardized was different from what had already been implemented in the Visual C++ implementation (I am not familiar with the history here; it may be that what was standardized matched another implementation.).
The Microsoft implementation of wide printf
and scanf
functions is not standard conforming, thus you get different results on Linux (standard-conforming) and Windows (broken).
The link Matt posted in his answer points to a MSDN page hinting at that misbehavior:
The C, S, and Z type characters, and the behavior of the c and s type characters when they are used with the printf and wprintf functions, are Microsoft extensions and are not ANSI compatible. Visual C++ does not support the F type character.
Emphasis mine. BTW: Here ANSI means all C standards, and by extension the C++ standards.
The specific issue is that MS redefined those conversion specifiers (c
s
) to expect UTF-16 when used with wide functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With