私はWindowsプログラミングに不慣れで、Petzoldの本を読んだ後、次のように思います。
文字列を宣言するためにTCHAR型と_T()関数を使用することはまだ良い習慣ですか、それとも新しいコードでwchar_tとL""文字列を使用する必要があるのですか?
Windows 2000以降のみを対象とし、コードは最初からi18nになります。
回答:
今日新しいプロジェクトを行っている場合でも、TCHAR構文を使用します。それを使用することとWCHAR構文の間にそれほど実用的な違いはなく、私は文字タイプが何であるかを明示するコードを好みます。ほとんどのAPI関数とヘルパーオブジェクトはTCHAR型(例:CString)を使用するため、それを使用するのは理にかなっています。さらに、ある時点でASCIIアプリでコードを使用することにした場合、またはWindowsがUnicode32に進化した場合など、柔軟性が得られます。
あなたがWCHARルートに行くことに決めたなら、私はそれについて明白になります。つまり、CStringの代わりにCStringWを使用し、TCHARに変換するときにマクロをキャストします(例:CW2CT)。
とにかく、それは私の意見です。
簡単な答え: いいえ。
すでに書いた他のすべてのように、多くのプログラマーはまだTCHARと対応する関数を使用しています。私の謙虚な意見では、全体の概念は悪い考えでした。UTF-16文字列処理は、単純なASCII / MBCS文字列処理とは大きく異なります。両方で同じアルゴリズム/関数を使用する場合(これはTCHARのアイデアの基になっています!)、単純な文字列の連結よりも少し多くのことを行うと、UTF-16バージョンで非常に悪いパフォーマンスが得られます(解析など)。主な理由は代理人です。
唯一の例外を除いて、あなたがたときに本当にUnicodeの私は、新しいアプリケーションでは、過去からこの荷物を使用する理由を見ていないサポートしていないシステムのためのアプリケーションをコンパイルする必要があります。
TCHARがもう使われるべきではないことに同意しますが、これが悪い考えであったことに同意しません。また、私はと思いならばあなたが選ぶ代わりに使用しての明示的であることをTCHAR明示的でなければならどこでも。つまり、宣言でTCHAR/ _TCHAR(など_tmain)を含む関数も使用しません。簡単に言えば、一貫性を保つ。+1、それでも。
TCHARは、最初に導入された目的を誤って伝えています。Win9xおよびWindowsNTベースのバージョンのWindows用のコードの開発を容易にするため。当時、Windows NTのUTF-16実装はUCS-2であり、文字列の解析/操作のアルゴリズムは同じでした。代理人はいませんでした。また、サロゲートを使用しても、DBCS(Windowsでサポートされている唯一のMBCSエンコーディング)とUTF-16のアルゴリズムは同じです。どちらのエンコーディングでも、コードポイントは1つまたは2つのコードユニットで構成されます。
Saschaに同意する必要があります。基礎となる前提TCHAR/ _T()/などは、あなたが「ANSI」ベースのアプリケーションを作成して、魔法のようにマクロを定義することによって、それをUnicodeサポートを与えることができるということです。しかし、これはいくつかの悪い仮定に基づいています。
ソフトウェアのMBCSバージョンとUnicodeバージョンの両方を積極的に構築していること
そうでなければ、あなたは滑ってchar*、多くの場所で普通の弦を使うでしょう。
_T( "...")リテラルで非ASCIIバックスラッシュエスケープを使用しないこと
「ANSI」エンコーディングがたまたまISO-8859-1でない限り、結果のリテラルchar*とwchar_t*リテラルは同じ文字を表しません。
そのUTF-16文字列は「ANSI」文字列と同じように使用されます
彼らはそうではありません。Unicodeは、ほとんどのレガシー文字エンコーディングには存在しないいくつかの概念を導入しています。サロゲート。文字を組み合わせる。正規化。条件付きで言語に依存するケーシングルール。
そしておそらく最も重要なのは、UTF-16がディスクに保存されたりインターネット経由で送信されたりすることはめったにないという事実です。UTF-8は外部表現に好まれる傾向があります。
アプリケーションがインターネットを使用していないこと
(今、これはあなたのソフトウェアにとって有効な仮定かもしれませんが...)
Webは、UTF-8と多数のまれなエンコーディングで実行されます。このTCHAR概念は、「ANSI」(UTF-8にすることはできません)と「Unicode」(UTF-16)の2つのみを認識します。Windows API呼び出しをUnicode対応にするのに役立つかもしれませんが、Webアプリや電子メールアプリをUnicode対応にするのには役に立たないのです。
Microsoft以外のライブラリを使用しないこと
他の誰も使用しませんTCHAR。 Pocoはstd::stringUTF-8を使用しています。 SQLiteにはそのAPIのUTF-8およびUTF-16バージョンがありますが、ありませんTCHAR。 TCHAR標準ライブラリにも含まれていstd::tcoutないので、自分で定義する場合を除いて、ありません。
有効なUTF-8ではないファイルを読み取る必要がある場合を除いて、「ANSI」エンコーディングが存在することを忘れてください。忘れてくださいTCHAR。常に「W」バージョンのWindowsAPI関数を呼び出します。 #define _UNICODE誤って「A」関数を呼び出さないようにするためです。
文字列には常にUTFエンコーディングを使用してください。文字列にはUTF-8、char文字列にはUTF-16(Windowsの場合)またはUTF-32(Unixライクなシステムの場合)wchar_t。 typedef UTF16そして、UTF32文字の種類は、プラットフォームの違いを避けるために。
#define _UNICODE。送信の終了:)
_UNICODEジェネリックテキストマッピングがCRTでどのように解決されるかを制御します。Windows APIのANSIバージョンを呼び出したくない場合は、を定義する必要がありますUNICODE。
それがまだ実際に行われているかどうか疑問に思っているなら、そうです-それはまだかなり使用されています。TCHARと_T( "")を使用している場合、誰もあなたのコードを面白く見ることはありません。私が現在取り組んでいるプロジェクトは、ANSIからUnicodeに変換することです。そして、ポータブル(TCHAR)ルートを使用します。
しかしながら...
私の投票は、すべてのANSI / UNICODEポータブルマクロ(TCHAR、_T( "")、およびすべての_tXXXXXX呼び出しなど)を忘れて、どこでもユニコードを想定することです。ANSIバージョンが必要になることがないのであれば、ポータブルであるという意味は本当にわかりません。私はすべてのワイド文字関数とタイプを直接使用します。すべての文字列リテラルの前にLを付けます。
はじめにWindowsにプログラミングの記事MSDNのは言います
新しいアプリケーションは、常に(APIの)Unicodeバージョンを呼び出す必要があります。
TEXTとTCHARのすべてのアプリケーションがUnicodeを使用する必要があるので、マクロは、今日あまり有用です。
私はに固執するだろうwchar_tとL""。
別のアプローチを提案したいと思います(どちらでもない)。
要約すると、UTF-8エンコーディングを想定してchar *とstd :: stringを使用し、API関数をラップする場合にのみUTF-16への変換を行います。
Windowsプログラムでのこのアプローチの詳細と正当化については、http://www.utf8everywhere.orgを参照してください。
TCHAR/WCHAR一部のレガシープロジェクトには十分かもしれません。しかし、新しいアプリケーションの場合、私はNOと言います。
これらすべてTCHAR/WCHARものは歴史的な理由のためにそこにあります。TCHARANSIテキストエンコーディング(MBCS)とUnicodeテキストエンコーディング(UTF-16)を切り替えるための、一見すっきりした方法(偽装)を提供します。これまで、人々は世界のすべての言語の文字数を理解していませんでした。彼らは、2バイトですべての文字を表すのに十分であり、したがって、を使用した固定長の文字エンコード方式であると想定しましたWCHAR。ただし、1996年にUnicode 2.0がリリースされた後は、これは当てはまりません。
つまり、CHAR/ WCHAR/TCHARでどちらを使用する場合でも、プログラムのテキスト処理部分は、国際化のために可変長文字を処理できる必要があります。
実際にはより多くのいずれかを選択よりも実行する必要がありますので、CHAR/ WCHAR/ TCHARWindowsでプログラミングします:
WCHAR。を使用します。この方法はUnicodeをサポートするWinAPIを使用する方が簡単なので。より詳細な読書のためにこの素晴らしいウェブサイトをチェックしてください:http: //utf8everywhere.org/
そのとおり; 少なくとも_Tマクロについては。ただし、ワイド文字についてはよくわかりません。
その理由は、WinCEまたはその他の非標準のWindowsプラットフォームをより適切にサポートするためです。コードがNTに残ることが100%確実な場合は、通常のC文字列宣言を使用できます。ただし、ライブラリを移植する必要がある場合に備えて、数千行のコードを実行してどこにでも追加するよりも、Windows以外のプラットフォームでそのマクロを#defineする方がはるかに簡単なので、より柔軟なアプローチを採用するのが最善です。 WindowsMobileに。
私見ですが、コードにTCHARが含まれている場合は、間違ったレベルの抽象化で作業しています。
テキスト処理を扱うときは、最も便利な文字列型を使用してください。これは、Unicodeをサポートするものになると思いますが、それはあなた次第です。必要に応じて、OSAPI境界で変換を行います。
ファイルパスを処理するときは、文字列を使用する代わりに、独自のカスタムタイプを作成してください。これにより、OSに依存しないパス区切り文字が可能になり、手動の文字列連結や分割よりもコード化が容易になり、さまざまなOS(ansi、ucs-2、utf-8など)への適応がはるかに簡単になります。 。
明示的なWCHAR以外のものを使用する理由は、移植性と効率だけです。
最終的な実行可能ファイルをできるだけ小さくしたい場合は、charを使用してください。
RAMの使用量を気にせず、国際化を単純な変換と同じくらい簡単にしたい場合は、WCHARを使用してください。
コードを柔軟にしたい場合は、TCHARを使用してください。
ラテン文字のみを使用する予定の場合は、ASCII / MBCS文字列を使用して、ユーザーがそれほど多くのRAMを必要としないようにすることもできます。
「最初からi18n」の人は、ソースコードのスペースを節約し、すべてのUnicode関数を使用するだけです。
古い質問に追加するだけです:
VS2010で新しいCLRC ++プロジェクトを開始します。マイクロソフト自身が使用L"Hello World"している」とナフ氏は語った。
CとC++。回答は、それぞれの作成者がいつでも削除できます。これは、その規定を使用するのに良い時期です。
TCHARポートに新しい意味を持っているWCHARのCHAR。
https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/use-utf8-code-page
Windows 10の最近のリリースでは、アプリにUTF-8サポートを導入する手段としてANSIコードページと-AAPIを使用しています。ANSIコードページがUTF-8用に構成されている場合、-AAPIはUTF-8で動作します。