我有一个多平台项目,它在 mac 上编译得很好,但是在 Windows 上,我所有带有 %s 的 swprintf 调用都在寻找 wchar_t 而不是 char * 我通过它。结果 M$ 认为在宽字符函数中让 %s 代表 char * 以外的东西会很有趣... http://msdn.microsoft.com/en-us/library/hf4y5e3w.aspx
无论如何,我正在寻找一种创造性的编码技巧,这比将 ifdef else 放在每个宽字符串调用周围更好
最佳答案
更新:VS 2015 CTP6 恢复了更改,Microsoft 再次与标准不同。
Visual Studio 14 CTP1以后会一直对待%s
作为窄字符串( 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
和 %hs
和 %hc
总是 char
. (记录在 VS2003 here 和 VC6 here(不确定 %ws
以及何时真正添加))制图
%s
在 Win9x 与 WinNT 的时代,通过使用 tchar.h
header 来调整函数的自然宽度真的很方便。您可以从同一来源构建窄版和宽版。当_UNICODE
在 tchar.h
中定义了函数映射到宽函数和 TCHAR
是 wchar_t
, 否则使用窄函数和 TCHAR
是 char
:_tprintf(_T("%c %s\n"), _T('a'), _T("Bcd"));
Windows SDK 头文件和那里存在的少数格式函数(wsprintf、wvsprintf、wnsprintf 和 wvnsprintf)使用了类似的约定,但它们由
UNICODE
控制。和 TEXT
而不是 _UNICODE
和 _T
/_TEXT
.如果您想支持较旧的 Windows 编译器,您可能有 3 种选择来在 Windows 上运行多平台项目:
1) 在 Windows 上编译为窄字符串项目,这可能不是一个好主意,在您的情况下,swprintf 仍会将 %s 视为 wchar_t*。
2) 使用类似于 inttypes.h 格式字符串工作方式的自定义定义:
#ifdef _WIN32
#define PRIs "s"
#define WPRIs L"hs"
#else
#define PRIs "s"
#define WPRIs L"s"
#endif
printf("%" PRIs " World\n", "Hello");
wprintf(L"%" WPRIs L" World\n", "Hello");
3) 创建您自己的 swprintf 自定义版本并将其与 Visual Studio 13 及更早版本一起使用。
关于visual-studio - Visual Studio swprintf 让我所有的 %s 格式化程序都想要 wchar_t * 而不是 char *,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10000723/