LPCSTR、LPCTSTR、およびLPTSTR


109

どう違いますかLPCSTRLPCTSTRおよびLPTSTR

なぜ我々はに文字列を変換するために、これを実行する必要がありますLV/ _ITEM構造体変数pszText

LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);

2
「文字列」のタイプを正確に言えますか?(CStringなど)
John Sibly 2008年

回答:


122

質問の最初の部分に答えるには:

LPCSTRconst文字列へのポインタです(LPはLong Pointerを意味します)

LPCTSTRconst TCHAR文字列へのポインタです(TCHARプロジェクトでUNICODEが定義されているかどうかによって、ワイド文字または文字になります)

LPTSTR(非const)TCHAR文字列へのポインタです

実際、過去にこれらについて話すときは、単純化のために「ポインタへのポインタ」句を省略しましたが、軌道上の明るさのレースで言及されているように、これらはすべてポインタです。

これは、C ++文字列を説明する素晴らしいcodeprojectの記事です(異なるタイプを比較するチャートについては、下の2/3を参照してください)。


18
すべてが間違っています。これらは文字列ではありません。それらはすべてポインタです。-1
オービットでの軽量レース、

8
C ++での文字列型を参照する簡潔にするための記述「....へのポインタ」私の経験では、除外するのが一般的ですが-あなたが技術的に正しいです@LightnessRacesinOrbit
ジョンSibly

2
@JohnSibly:Cでは、はい。C ++では、絶対にすべきではありません!!
オービットのライトネスレース2015年

4
codeprojectの記事は15年前に書かれており、更新されない限り、常に2バイトであるUnicode文字に関する誤解を招く仮定が含まれていることに注意してください。それは完全に間違っています。UTF16も可変長です...ワイド文字はUCS-2でエンコードされていると言った方がはるかに良く、この文脈での「Unicode」はUCS-2を指します。
u8it 2017年

1
うーん...この場合、@ LightnessRacesinOrbit、C ++でC文字列を参照するときは、「...へのポインタ」を省略してもかまわないという補遺を追加します。 (減衰した)文字列リテラル、またはCで記述されたコードとのインターフェース/操作時に、C ++型ではなくC型に依存している、またはを介しextern "C"たCリンケージがある。それとは別に、そうです、「ポインタ」ビットか、C文字列としての特定の説明が必要です。
ジャスティン時間-モニカを復活

87

素早く汚い:

LP== LオングPの ointer。ポインタまたはchar *を考えてください

C= C onst、この場合、文字列がconstであって、ポインタがconstではないことを意味すると思います。

STRある文字列は、

これTは、コンパイルオプションに応じて、ワイド文字または文字(TCHAR)用です。


16
Tはワイド文字用ではなく、さまざまな文字タイプ用です。Wはワイド用です(WCHARと同様)。UNICODEが定義されている場合はTCHAR == WCHAR、それ以外の場合はTCHAR == CHAR。したがって、UNICODEが定義されていない場合、LPCTSTR == LPCSTRになります。
jalf

10
それが私が「コンパイルオプションに依存する」と書いた理由です
Tim

14
私はこのタイプの説明が大好きです:)。
どうも

@ jalf、Tは何の略ですか?
Pacerier


36

8ビットAnsiString

  • char:8ビット文字-基礎となるC / C ++データ型
  • CHAR:のエイリアスchar-Windowsデータ型
  • LPSTRL ong P ointer)の nullで終了する文字列CHAR
  • LPCSTRL ong P ointer)の nullで終了する定数文字列CHAR

16ビットUnicodeStrings

  • wchar_t:16ビット文字-基礎となるC / C ++データ型
  • WCHAR:のエイリアスwchar_t-Windowsデータ型
  • LPWSTRL ong P ointer)の nullで終了する文字列WCHAR
  • LPCWSTRL ong P ointer)の nullで終了する定数文字列WCHAR

UNICODE定義によって

  • TCHARWCHARUNICODEが定義されている場合のエイリアス。さもないとCHAR
  • LPTSTRL ong P ointer)の nullで終了する文字列TCHAR
  • LPCTSTRL ong P ointer)の nullで終了する定数文字列TCHAR

そう

| Item              | 8-bit        | 16-bit      | Varies          |
|-------------------|--------------|-------------|-----------------|
| character         | CHAR         | WCHAR       | TCHAR           |
| string            | LPSTR        | LPWSTR      | LPTSTR          |
| string (const)    | LPCSTR       | LPCWSTR     | LPCTSTR         |

ボーナスリーディング

TCHARテキスト文字 archive.is


4
それがとても新しいので、この答えがトップになることは決してありません..それは本当にSOが修正する必要があるものです。これは断然最良の答えです。
Dan Bechard

これは私が仕事でユニコードプロジェクトをしている間、私にとても役立ちます。ありがとう!
Yoon5oo

素敵な答え。ユニコードバージョンはUTF16を使用しているので、16ビットの各チャンクは文字ではなくコード単位であることを付け加える価値があると思います。名前は歴史的なものです(Unicode === UCS2の場合)。
マーガレットブルーム

5

ジョンとティムの答えに追加。

Win98用にコーディングしていない限り、アプリケーションで使用する必要がある6つ以上の文字列タイプは2つだけです。

  • LPWSTR
  • LPCWSTR

残りはANSIプラットフォームまたはデュアルコンパイルをサポートするためのものです。それらは、以前ほど重要ではありません。


2
@BlueRaja、私は私の回答で主にCベースの文字列を参照していました。しかし、C ++のstd::string場合は、ASCIIベースの文字列であるため、回避し、std::wstring代わりに使用します。
JaredPar

1
関数のASCII(* A)またはワイド文字(* W)バージョンを直接呼び出す場合を除き、LPTSTRおよびLPCTSTRを使用する必要があります。これらは、コンパイル時に指定する文字幅のエイリアスです。
osvein 2017年

...そしてMicrosoftが*AWinAPI のバージョンをUTF-8コードページと互換性のあるものにすることに取り組んでいる今、それらは突然より関連性があります。; P
ジャスティン時間-モニカを復活

4

質問の2番目の部分に答えるには、次のようなことをする必要があります

LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);

MSのLVITEM構造体にはLPTSTR、つまり変更可能な T文字列ポインタがあり、LPCTSTR。あなたがしていることは

1)stringCString推測で)a をLPCTSTR(実際には文字バッファーのアドレスを読み取り専用ポインターとして取得することを意味しますます

2)const-nessをキャストして、読み取り専用ポインターを書き込み可能ポインターに変換します。

それはdispinfoあなたのListView呼び出しがそれ介して書き込もうとする可能性があるかどうかに使用されるものに依存しますpszText。もしそうなら、これは潜在的に非常に悪いことです:結局、あなたは読み取り専用のポインタを与えられて、それを書き込み可能として扱うことに決めました:多分それが読み取り専用だった理由があるかもしれません!

それがaである場合は、CString使用するオプションがあります。これstring.GetBuffer()により、意図的に書き込み可能になりLPTSTRます。ReleaseBuffer()文字列が変更された場合は、必ず呼び出すことを忘れないでください。または、ローカルの一時バッファを割り当てて、そこに文字列をコピーすることもできます。

99%の時間はこれが不要でありLPCTSTRLPTSTR意志で動作するように扱われます...しかし、ある日、あなたがそれを最も期待しないとき...


1
Cスタイルのキャストは避け、xxx_cast<>()代わりに使用してください。
18年

@harperあなたはまったく正しいです-しかし私はOPを引用していました、それは彼が尋ねていたコードです。私が自分でコードを作成した場合、xxx_cast<>2つの異なるブラケットベースのキャストスタイルを混在させるのではなく、コードを使用したはずです。
AAT 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.