我有一个可以在mac上编译的多平台项目,但在Windows上,所有带有%s的swprintf调用都在寻找wchar_t而不是传递它的char * im。结果M $认为让%s代表广泛字符函数中除char *以外的东西会很有趣...... http://msdn.microsoft.com/en-us/library/hf4y5e3w.aspx
无论如何我正在寻找一种创造性的编码技巧,比把ifdef以每个宽字符串调用结束更好
答案 0 :(得分:4)
%s
,否则 Visual Studio 14 CTP1及更高版本将始终将char*
视为一个较窄的字符串(_CRT_STDIO_LEGACY_WIDE_SPECIFIERS
)。它还添加了T长度修改器扩展,它映射到MS称为“自然”宽度。 sprintf
%Ts
为char*
,而swprintf
%Ts
为wchar_t*
。
在Visual Studio 13及更早版本中,%s
/ %c
映射到函数/格式字符串的自然宽度,而%S
/ %C
映射到相反的天然的:
printf("%c %C %s %S\n", 'a', L'B', "cd", L"EF");
wprintf(L"%c %C %s %S\n", L'a', 'B', L"cd", "EF");
您还可以使用长度修改器强制特定宽度:%ls
,%lc
,%ws
和%wc
始终表示wchar_t
和{{1 }}和%hs
始终为%hc
。 (记录为VS2003 here和VC6 here(不确定char
以及何时真正添加)
在Win9x与WinNT的时代,将%ws
映射到函数的自然宽度非常方便,使用tchar.h
header可以从同一个源构建窄版和宽版。定义%s
后,_UNICODE
中的函数映射到宽函数,tchar.h
映射为TCHAR
,否则使用窄函数,wchar_t
为{{1} }}:
TCHAR
Windows SDK头文件使用的类似约定和那里存在的少数格式函数(wsprintf,wvsprintf,wnsprintf和wvnsprintf)但它们由char
和_tprintf(_T("%c %s\n"), _T('a'), _T("Bcd"));
控制而不是UNICODE
和TEXT
/ _UNICODE
。
如果您想支持较旧的Windows编译器,您可能有3种选择使多平台项目在Windows上运行:
1)在Windows上编译为一个窄字符串项目,可能不是一个好主意,在您的情况下,swprintf仍会将%s视为wchar_t *。
2)使用类似于inttypes.h格式字符串工作的自定义定义:
_T
3)创建自己的swprintf自定义版本,并将其与Visual Studio 13及更早版本一起使用。
答案 1 :(得分:2)
使用始终为%ls
的{{1}}格式。
答案 2 :(得分:2)
您可以使用"%Ts"格式说明符或您可以定义_CRT_STDIO_LEGACY_WIDE_SPECIFIERS = 1.
阅读本文: