更新:VS 2015 CTP6は変更を元に戻し、Microsoftは再び標準とは異なる動作をしています。
Visual Studio 14 CTP1 以降では、を定義しない限り、常に%s狭い文字列(char*)として扱われます_CRT_STDIO_LEGACY_WIDE_SPECIFIERS。また、MSが「自然な」幅と呼ぶものにマップするT長さ修飾子拡張を追加しました。forisおよびforis 。sprintf %Ts_char*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および常に平均およびおよびは常に。(VS2003についてはここに、VC6についてはここに文書化されています(実際にいつ追加されたかはわかりません)) %lc%ws%wcwchar_t%hs%hcchar%ws
関数の自然な幅へのマッピング%sは、Win9xとWinNTの時代には非常に便利でした。tchar.hヘッダーを使用することで、同じソースから狭いリリースと広いリリースを作成できました。_UNICODEが定義されている場合、関数tchar.hはワイド関数にマップされ、TCHARはですwchar_t。それ以外の場合、ナロー関数が使用され、次のようになりTCHARますchar。
_tprintf(_T("%c %s\n"), _T('a'), _T("Bcd"));
Windows SDKヘッダーファイルとそこに存在するいくつかのフォーマット関数(wsprintf、wvsprintf、wnsprintf、およびwvnsprintf)で使用される同様の規則がありますが、これらはandUNICODEによって制御されます。TEXT_UNICODE_T_TEXT
古いWindowsコンパイラをサポートしたい場合は、Windowsでマルチプラットフォームプロジェクトを機能させるために、おそらく3つの選択肢があります。
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を作成し、VisualStudio13以前で使用します。