以下代码行为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中的错误,或者我错过了什么。问候。
答案 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
格式说明符。或者,h
和l
长度修饰符可用于显式指定字符串参数是窄字符串或宽字符串。
除了其他优点之外,这些函数的Visual C ++实现使得可以通过the _TCHAR
mappings in <tchar.h>
轻松迁移旧代码以使用Unicode字符串。遗憾的是,标准化的内容与Visual C ++实现中已经实现的内容不同(我不熟悉这里的历史记录;可能是标准化的内容与另一个实现相匹配。)。
答案 1 :(得分:3)
广泛printf
和scanf
函数的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字符串输入都是宽的。