web-dev-qa-db-ja.com

TCHARはまだ関連していますか?

私はWindowsプログラミングが初めてで、Petzoldの本を読んだ後、私は疑問に思います。

TCHAR型と_T()関数を使用して文字列を宣言するか、単にwchar_tおよびL""新しいコードの文字列?

Windows 2000以降のみを対象とし、コードは起動時から i18n になります。

86
Fábio

今日新しいプロジェクトを行っていた場合、TCHAR構文を引き続き使用します。それを使用することとWCHAR構文を使用することとの間に実際的な違いはあまりありません。文字タイプが明示されているコードを好みます。ほとんどのAPI関数とヘルパーオブジェクトは、TCHAR型(CStringなど)を使用するため、使用するのが理にかなっています。さらに、ある時点でASCIIアプリでコードを使用することを決定した場合、またはWindowsがUnicode32などに進化した場合などに柔軟性をもたらします。

あなたがWCHARルートに行くことに決めたら、私はそれについて明示するでしょう。つまり、CStringの代わりにCStringWを使用し、TCHARに変換するときにマクロをキャストします(例:CW2CT)。

とにかく、それは私の意見です。

15
Nick

短い答え:[〜#〜] no [〜#〜]

他のすべての人がすでに書いたように、多くのプログラマーはまだTCHARと対応する関数を使用しています。私の謙虚な意見では、コンセプト全体が悪いアイデアでしたTF-16 文字列処理は、単純なASCII/MBCS文字列処理とは大きく異なります。両方で同じアルゴリズム/関数を使用する場合(これがTCHARのアイデアの根拠です!)、単純な文字列の連結よりも少し多く行うと、UTF-16バージョンで非常に悪いパフォーマンスが得られます解析など)。主な理由は Surrogates です。

あなたが実際にユニコードをサポートしていないシステム用にアプリケーションをコンパイルしなければならない場合の唯一の例外を除いて、私は過去からこの荷物を使用する理由はない新しいアプリケーションで。

89
Sascha

私はサシャに同意しなければなりません。 TCHAR/_T() /などの基本的な前提は、「ANSI」ベースのアプリケーションを記述し、マクロを定義することで魔法のようにUnicodeサポートを提供できることです。しかし、これはいくつかの悪い仮定に基づいています。

あなたのソフトウェアのMBCSとUnicodeバージョンの両方を積極的にビルドすること

そうでなければ、willスリップして、多くの場所で普通のchar*文字列を使用します。

_ T( "...")リテラルで非ASCIIバックスラッシュエスケープを使用しないこと

「ANSI」エンコーディングがISO-8859-1である場合を除き、結果のchar*およびwchar_t*リテラルは同じ文字を表しません。

UTF-16文字列は「ANSI」文字列と同じように使用されます

そうではありません。 Unicodeには、ほとんどのレガシー文字エンコーディングには存在しないいくつかの概念が導入されています。代理。文字を組み合わせます。正規化。条件付きおよび言語依存の大文字小文字ルール。

そしておそらく最も重要なことは、UTF-16がディスクに保存されたり、インターネット経由で送信されることはめったにないという事実です。UTF-8は外部表現に優先される傾向があります。

アプリケーションがインターネットを使用しないこと

(今、これはyour softwareの有効な仮定かもしれませんが、...)

WebはUTF-8で実行されます および より多くのまれなエンコーディングTCHARの概念は、「ANSI」( ca n'tはUTF-8 )と「Unicode」(UTF-16)の2つのみを認識します。 Windows API呼び出しをUnicode対応にするには便利かもしれませんが、Webアプリや電子メールアプリをUnicode対応にするには役に立たないでしょう。

Microsoft以外のライブラリを使用しないこと

誰もTCHARを使用しません。 Pocostd::stringおよびUTF-8を使用します。 SQLite にはUTF-8およびUTF-16バージョンのAPIがありますが、TCHARはありません。 TCHARは標準ライブラリにもないため、自分で定義したい場合を除き、std::tcoutはありません。

TCHARの代わりに私がお勧めすること

有効なUTF-8ではないファイルを読み取る必要がある場合を除き、「ANSI」エンコーディングが存在することを忘れてください。 TCHARも忘れてください。 Windows API関数の「W」バージョンを常に呼び出します。 #define _UNICODEは、誤って "A"関数を呼び出さないようにするためです。

文字列には常にUTFエンコードを使用します。char文字列にはUTF-8、wchar_t文字列にはUTF-16(Windowsの場合)またはUTF-32(Unix系システム)を使用します。プラットフォームの違いを避けるためのtypedefUTF16およびUTF32文字タイプ。

77
dan04

まだ実際に使用されているかどうか疑問に思っているなら、はい-まだかなり使用されています。 TCHARと_T( "")を使用している場合、誰もあなたのコードを面白いとは思わないでしょう。私が現在取り組んでいるプロジェクトは、ANSIからUnicodeに変換しています-そして、ポータブル(TCHAR)ルートを目指しています。

ただし...

私の投票は、すべてのANSI/UNICODEポータブルマクロ(TCHAR、_T( "")、およびすべての_tXXXXXX呼び出しなど)を忘れて、どこでもUnicodeを想定することです。あなたがANSIバージョンを必要としないならば、私は本当に移植性のあるポイントを見ません。すべてのワイド文字関数とタイプを直接使用します。すべての文字列リテラルにLを前に付けます。

18
Aardvark

Windowsプログラミング入門記事 MSDN

新しいアプリケーションは、常に(APIの)Unicodeバージョンを呼び出す必要があります。

[〜#〜] text [〜#〜]および[〜#〜] tchar [〜#〜 ]マクロは、すべてのアプリケーションでUnicodeを使用する必要があるため、今日ではあまり役に立ちません。

私はwchar_tおよびL""

11
Steven

別のアプローチを提案したいと思います(2つとも)。

要約すると、UTF-8エンコードを想定してchar *とstd :: stringを使用し、API関数をラップする場合にのみUTF-16への変換を行います。

Windowsプログラムでのこのアプローチの詳細と正当性は、 http://www.utf8everywhere.org にあります。

10

TCHAR/WCHARは、一部のレガシープロジェクトには十分かもしれません。しかし、新しいアプリケーションの場合、[〜#〜] no [〜#〜]と言います。

これらのすべてのTCHAR/WCHARのものは、歴史的な理由から存在しています。 TCHARは、ANSIテキストエンコーディング(MBCS)とUnicodeテキストエンコーディング(UTF-16)を切り替えるための、一見きれいな方法(変装)を提供します。過去には、人々は世界中のすべての言語の文字数を理解していませんでした。彼らは、すべての文字を表現するには2バイトで十分であり、したがってWCHARを使用した固定長の文字エンコード方式を持っていると想定していました。ただし、これは1996でのUnicode 2.0のリリース後には当てはまりません。

つまり:CHAR/WCHAR/TCHARでどちらを使用しても、プログラムのテキスト処理部分は処理できるはずです国際化のための可変長文字

したがって、実際には、Windowsでのプログラミングでは、CHAR/WCHAR/TCHARから1つを選択する以上のことを行う必要があります。

  1. アプリケーションが小さく、テキスト処理を伴わない場合(つまり、テキスト文字列を引数として渡すだけの場合)、WCHARを使用します。この方法は、UnicodeをサポートするWinAPIで作業する方が簡単だからです。
  2. そうでなければ、UTF-8を内部エンコーディングとして使用し、テキストを文字列またはstd :: stringに保存することをお勧めします。そして、WinAPIを呼び出すときにそれらをUTF-16に変換します。 TF-8 が主なエンコーディングになり、UTF-8文字列を処理する便利なライブラリとツールがたくさんあります。

詳細については、この素晴らしいWebサイトをご覧ください。 http://utf8everywhere.org/

6
LeOpArD

そのとおり;少なくとも_Tマクロの場合。ただし、ワイド文字に関することはよくわかりません。

その理由は、WinCEまたはその他の非標準のWindowsプラットフォームをより適切にサポートするためです。コードがNT上に残ることを100%確信している場合は、おそらく通常のC文字列宣言を使用できます。ただし、ライブラリを移植する必要がある場合に数千行のコードを調べてどこにでも追加するのに比べて、Windows以外のプラットフォームでマクロを#defineする方がはるかに簡単なので、より柔軟なアプローチに向かうのが最善ですWindows Mobileへ。

4
Nik Reiman

明示的なWCHAR以外のものを使用するのは、移植性と効率性だけです。

最終的な実行可能ファイルを可能な限り小さくする場合は、charを使用します。

RAMの使用を気にせず、国際化を単純な翻訳と同じくらい簡単にしたい場合は、WCHARを使用します。

コードを柔軟にしたい場合は、TCHARを使用します。

ラテン文字のみを使用する場合は、ASCII/MBCS文字列を使用して、ユーザーがそれほど多くのRAMを必要としないようにすることもできます。

「最初からi18n」を使用している人は、ソースコードスペースを節約し、すべてのUnicode関数を使用してください。

2
Trololol

私見ですが、コードにTCHARが含まれている場合、間違った抽象化レベルで作業しています。

whatever文字列型を使用すると、テキスト処理を処理する際に最も便利です。これはユニコードをサポートするものになりますが、それはあなた次第です。必要に応じて、OS APIの境界で変換を行います。

ファイルパスを扱うときは、文字列を使用する代わりに独自のカスタムタイプを作成します。これにより、OSに依存しないパスセパレーターが可能になり、手動で文字列を連結および分割するよりもコードへのインターフェイスが簡単になり、さまざまなOS(ansi、ucs-2、utf-8など)に適応しやすくなります。

2
snemarch