来自http://www.globalyzer.com/gzserver/help/localeSensitiveMethods/formatting.htm#larges
不合格的字符串说明符(大 %S)
这些表显示了 Windows 和 ANSI 如何根据 %S 说明符和函数调用的样式(单、通用或宽)处理参数:
Windows 函数说明符参数需要是
printf/sprintf (单个/MBCS) %S wchar_t*
_tprintf/_stprintf(通用)%S(不要使用)
wprintf/swprintf(宽)%S char*
ANSI 函数说明符参数需要是
printf/sprintf (单个/MBCS) %S wchar_t*
wprintf/swprintf(宽)%S wchar_t*
ANSI 和 Windows 在单字节或宽度方面基本上都将 %S 视为与 %s 相反,这具有讽刺意味的是,Windows 和 ANSI 再次以不同的方式处理这些说明符。
请注意,ANSI 本质上总是以与 %ls 相同的方式处理 %S,换句话说,它总是被假定为宽字符串。
另一方面,Windows 根据函数调用的类型对 %S 进行不同的处理。对于单字节函数调用,%S 的作用类似于宽 %ls 说明符,但对于宽函数调用,%S 的作用类似于单字节 %hs 说明符。
此说明符不应用于 Windows 通用调用。由于 %S 是 %s 的“对立面”,如果 _UNICODE 标志关闭,则参数需要是宽的,如果 _UNICODE 标志打开,则需要单字节。TCHAR 泛型类型不能以这种方式工作,并且没有“反 TCHAR”类型的数据类型。
我在 Visual C++ 2010 中尝试了以下操作:
#include "stdafx.h"
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
WCHAR cBuf[MAX_PATH];
TCHAR tBuf[MAX_PATH];
wcsncpy_s(cBuf, L"Testing\r\n", MAX_PATH);
_tcsncpy_s(tBuf, _T("Testing\r\n"), MAX_PATH);
printf("%S", cBuf); // Microsoft extension
printf("%ls", cBuf); // works in VC++ 2010
wprintf(L"%s", cBuf); // wide
_tprintf(_T("%s"), tBuf); // single-byte/wide
return 0;
}
设置:
/ZI /nologo /W3 /WX- /Od /Oy- /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /GS /fp:精确 /Zc:wchar_t /Zc:forScope /Yu"StdAfx.h" /Fp"Debug\TestWchar.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /analyze - /错误报告:队列