Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

swprintf() with narrow strings

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.

like image 278
Peter Avatar asked May 09 '14 19:05

Peter


People also ask

What is Swprintf?

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.

What is Wsprintf C++?

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.


2 Answers

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.).

like image 75
James McNellis Avatar answered Oct 23 '22 04:10

James McNellis


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.

like image 24
Deduplicator Avatar answered Oct 23 '22 05:10

Deduplicator