5

Macでうまくコンパイルできるマルチプラットフォームプロジェクトがありますが、Windowsでは、%sを使用したすべてのswprintf呼び出しで、char*imが渡す代わりにwchar_tを探しています。M $は、ワイド文字関数で%sをchar*以外のものを表すのは面白いだろうと考えていました... http://msdn.microsoft.com/en-us/library/hf4y5e3w.aspx

とにかく、私はifdefを置くよりも優れた創造的なコーディングのトリックを探しています。

4

3 に答える 3

4

更新: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以前で使用します。

于 2012-04-03T20:54:45.763 に答える
2

%ls常にを意味する形式を使用してくださいwchar_t*

于 2012-04-03T20:25:31.237 に答える
2

「%Ts」フォーマット指定子を使用するか、_CRT_STDIO_LEGACY_WIDE_SPECIFIERS=1を定義できます。

これを読む:

http://blogs.msdn.com/b/vcblog/archive/2014/06/18/crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1.aspx

于 2014-11-22T00:36:42.877 に答える