visual-studio - Visual Studio swprintf 让我所有的 %s 格式化程序都想要 wchar_t * 而不是 char *

标签 visual-studio printf

我有一个多平台项目,它在 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 %Tschar*swprintf %Tswchar_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 来调整函数的自然宽度真的很方便。您可以从同一来源构建窄版和宽版。当_UNICODEtchar.h 中定义了函数映射到宽函数和 TCHARwchar_t , 否则使用窄函数和 TCHARchar :
_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/

相关文章:

c - C 中的 printf() 函数

c - printf() 中的 scanf() 如何工作?

c编程printf格式搜索表达式

visual-studio - 如何从TFS项目创建分支(从带标签的版本)

c# - C#如何验证C#私有(private)定义?

c++ - 如何删除、重新安装和/或查找有关 Visual Studio 2008 修补程序的信息?

字符数组和指针

c++ - statvfs 问题 - printf/调试器

c++ - Visual Studio for C++ __cplusplus 支持的语言显示为 C++98

visual-studio - 如何在未经我许可的情况下让 Visual Studio 在构建期间停止复制 DLL?