带有窄字符串的swprintf()

时间:2014-05-09 19:00:54

标签: c++ c visual-studio-2010 visual-c++

以下代码行为Visual Studio 2010提供了垃圾:

swprintf(buf, L"Value is %s", "abcd");

但是,相同的代码在Linux上运行良好。

通过试用,我可以在Visual Studio下使用%S代替%s。

swprintf(buf, L"Value is %S", "abcd");

我想知道这是否是Visual Studio 2010中的错误,或者我错过了什么。问候。

4 个答案:

答案 0 :(得分:4)

这是一个"错误,"虽然行为是设计的。宽字符串printf和scanf函数的初始Visual C ++实现早于它们在C中的标准化,并且在某些情况下,行为偏离了C标准库规范所要求的行为。

在C标准库规范中,%s%c格式说明符必须始终与char数组或元素配对,并且l长度修饰符必须为在提供wchar_t数组或元素时使用。

在这些函数的Visual C ++实现中(documentation),%s%c格式说明符期望" natural"的相应参数。宽度。对于窄字符串printf和scanf函数,需要char指针或元素,对于宽字符串函数,需要wchar_t指针或元素。传递"其他"的字符串宽度,可以使用%S%C格式说明符。或者,hl长度修饰符可用于显式指定字符串参数是窄字符串或宽字符串。

除了其他优点之外,这些函数的Visual C ++实现使得可以通过the _TCHAR mappings in <tchar.h>轻松迁移旧代码以使用Unicode字符串。遗憾的是,标准化的内容与Visual C ++实现中已经实现的内容不同(我不熟悉这里的历史记录;可能是标准化的内容与另一个实现相匹配。)。

答案 1 :(得分:3)

广泛printfscanf函数的Microsoft实现不符合标准,因此您在Linux(符合标准)和Windows(已损坏)上会得到不同的结果。

The link Matt posted in his answer指向MSDN页面,暗示了这种不当行为:

  当与printf和wprintf函数一起使用时,

C,S和Z类型字符以及 c和s类型字符的行为是Microsoft扩展且不是ANSI兼容。 Visual C ++不支持F类型字符。

强调我的。 BTW:这里ANSI表示所有C标准,并且扩展了C ++标准。

具体问题是MS重新定义了这些转换说明符(c s),以便在使用宽函数时期望UTF-16。

答案 2 :(得分:0)

%s和%S有不同的含义:

s:与printf函数一起使用时,指定单字节或多字节字符串;与wprintf函数一起使用时,指定宽字符串。字符显示到第一个空字符或直到达到精度值。

S:与printf函数一起使用时,指定宽字符串;与wprintf函数一起使用时,指定单字节或多字节字符串。字符显示到第一个空字符或直到达到精度值。

这就是为什么

swprintf(buf, L"Value is %S", "abcd");

显示正确的值。

MSDN链接为here

答案 3 :(得分:0)

“abcd”是一个很窄的字符串,因为你省略了'L'。 swprintf()期望它的所有%s字符串输入都是宽的。