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は常に%Sを%lsと同じように扱うことに注意してください。つまり、常に幅の広い文字列であると見なされます。
一方、Windowsは、関数呼び出しのタイプに基づいて%Sを異なる方法で処理します。シングルバイト関数呼び出しの場合、%Sはワイド%ls指定子のように機能しますが、ワイド関数呼び出しの場合、%Sはシングルバイト%hs指定子のように機能します。
この指定子は、WindowsGeneric呼び出しには使用しないでください。%Sは%sの「反対」であるため、_UNICODEフラグがオフの場合はパラメーターをワイドにする必要があり、_UNICODEフラグがオンの場合は1バイトにする必要があります。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 / analysis -/ errorReport:queue