传递`char const *`匹配`L“%s”`说明符时`swprintf`的行为

时间:2013-09-10 09:44:44

标签: c++ c visual-c++-2012

我正在编写Excel插件,需要生成wchar_t Excel的输出(虽然在内部,我们是100%char,和 实际上将char限制为纯ASCII。有一次,我正在使用 swprintf进行转换:

static wchar_t buffer[ 32369 ];
buffer[0] = swprintf( buffer + 1, sizeof(buffer) - 1, L"#%s!", message );

Excel显示某种CJK字符,但message (类型char const*)是一个以空字符结尾的字符串 没有可打印ASCII之外的字符(十六进制值0x20-0x7E)。

我在一个小测试程序中试过这个,以十六进制转储 生成的字符串,看起来VC ++正在处理message 好像它是一个wchar_t const*(虽然它似乎 正确识别'\0',虽然它是单一的 字节);这导致wchar_t的值为0x6568 (而不是我期待的0x0068, 0x0065)。

根据C99标准,对于"%s"说明符, swprintf应转换char const*中的字符 “好像通过反复调用mbrtowc函数[...]”。是 我看到的行为是Visual C ++库中的错误, 或者我在全球语言环境中是否有某些内容 改变?

(FWIW:当我用g ++编译并运行我的小测试程序时, 我得到了我期望的行为。但是,G ++不是一个选项 我们的Excel插件,至少目前不是。)

2 个答案:

答案 0 :(得分:11)

请注意,来自MSDN的swprintf

  

swprintf是sprintf的宽字符版本; swprintf的指针参数是宽字符串。

然后在示例中:

wchar_t buf[100];
int len = swprintf( buf, 100, L"%s", L"Hello world" );

所以至少微软记录了这一点。

然后在format specifiers

的页面中
  

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

然后

  

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

所以你想要的是大写的%S

甚至可以看到这个类似的问题:visual studio swprintf is making all my %s formatters want wchar_t * instead of char *他们建议使用%ls(始终考虑参数wchar_t*)和%hs(始终考虑参数char*

答案 1 :(得分:2)

调用swprintf时,说明符%s 被解释为指向宽字符串,即wchar_t指针。而是使用%S (大写S)格式说明符,因为它将正确使用您传递的char* message

来自Microsoft的printf类型字段字符文档:

  • s ,字符串,与 printf 函数一起使用时,指定单字节字符串;与 wprintf 函数一起使用时,指定宽字符串。字符将打印到第一个空字符或直到达到精度值。
  • S ,字符串,与 printf 函数一起使用时,指定宽字符串;与 wprintf 函数一起使用时,指定单字节字符串。字符将打印到第一个空字符或直到达到精度值。