2013-05-23 24 views
10

std::stringからLPCTSTRへの変換の一般的な質問の新しいバージョンです。std :: string to LPCTSTR

CreateDirectory(path.c_str(),NULL); 

そして、まだ、コンパイラはcannot convert from const char * to LPCTSTRため、エラーを与える:私はこれを行う必要があることを学んだ別のSOの記事から読み

私が試した:

CreateDirectory((LPCTSTR)path.c_str(),NULL); 

んがエラーを!それでも(正しい場所に)作成したディレクトリが呼び出される

:あなたが推測できるように、私が望んでいたまさにではありません

D:\\something\\㩄ぜ弲久䅓余屓䱆彄湡敤屲䵉ⴱ㠶ⴰⵃㅇ㉜洰⵭就䥄牃獥汵獴촀췍췍췍췍췍췍췍﷍﷽꯽ꮫꮫꮫﺫﻮﻮ 

...

だから私は何をしないのですか?それはUNICODE/ANSIに関連していますか?どうすれば解決できますか?

+4

これから学ぶレッスンはキャストしません。盲目的にキャストするのは、コンパイラにシャットダウンするように伝えることだけです。コンパイラを聞いてみてください。 –

+2

@DavidHeffernan私は全知のマスターコンパイラに耳を傾けます! –

答えて

7

LPCTSTRwchar_t*またはchar*に解決されているかどうかは、ビルドがユニコード(ユニコードフラグが設定されているかどうか)をサポートしているかどうかによって決まります。

char*バージョンを明示的に呼び出すには、CreateDirectoryA()を呼び出します。

+0

これは不完全な答えです。CreateDirectoryAは、文字列がユーザーの現在のコードページにあるとみなします。多くのコードでは、UTF-8を保持するためにstd :: stringsを使用しています(まれには他のエンコーディングもあります)。この場合、std :: stringをUTF-16 WCHAR文字列に変換(型変換ではない)し、 CreateDirectoryW。ここでの理論とコードサンプル:http://utf8everywhere.org/ –

6

What-are-TCHAR-WCHAR-LPSTR-LPWSTR-LPCTSTR-etcをご覧ください。 (LPCTSTR)path.c_str()あなたは、元の文字列から2つの文字を取って、そこから作成されます:あなたはプロジェクトのためにUnicodeを設定している可能性がありとLPCSTRconst wchar_t *に「翻訳」され、これによりconst char *

と互換性がありません。これよりもMSVCを使用している場合1つのUnicode wchar_t文字。それはあなたが "中国語"文字を取得している通りです。

1

代わりにCreateDirectoryAを使用してください。 CreateDirectoryは、ビルド構成によってはCreateDirectoryAまたはCreateDirectoryWのいずれかに展開されるマクロです。それぞれLPCSTRLPCWSTRとなります。 LPCSTR(これはc_str()があなたのものです)を知っている場合は、最初のものを使用してください。

5

ユニコード用にコンパイルしています。つまり、CreateDirectoryは、ワイド文字版CreateDirectoryWのエイリアスです。ただし、プログラムのテキストはANSIを使用してエンコードされます。これは、プログラムが国際化を適切に処理できないことを意味します。

コンパイラは、CreateDirectoryWが期待するテキストエンコーディングと、提供しているテキストエンコーディングとの間に不一致があることを伝えています。この不一致を解消するためにCreateDirectoryAと呼ぶことができますが、これはルート問題、つまりプログラムでANSIテキストを使用しているという事実を永続させるだけです。

したがって、すべてのテキストをUnicodeとしてエンコードすることをお勧めします。 stringを停止し、wstringを使い始める。あなたがwstringpathを変更すると

CreateDirectory(path.c_str(),NULL); 

は正しいです。

+0

ええ、私はホールプログラムで一度しか使用しないでしょう。つまり、ANSIからUNICODEへの変更は今、退屈な作業です。コードは簡単です。あなたの答えは本当に面白いです、私は将来心に留めておきます。 –

4

あなたが見つけるしようとすると、この質問は、 "STD(::) LPCTSTRする文字列" ポップアップしたよう

はここwstring

string path_str = "Yay!"; //your string containing path 
wstring path_wstr(path_str.begin(), path_str.end()); 
//then this should work: 
CreateDirectory(path_wstr.c_str(),NULL); 

重要を使用してLPCTSTRとして&パスstd::stringを変換する方法方法です注:によってアドリアンマッカーシー

ソース文字列がASCIIであるか、ANSIで、 現在のコードページがWindows-1252(これはLatin-1に非常に似ています)の場合、これは問題ありません。 ソースがUTF-8または別のコードページの場合、これは 問題を隠すだけです。

+0

ソース文字列がASCIIの場合、またはANSIの場合は現在のコードページがWindows-1252(Latin-1に非常に似ています)の場合は問題ありません。ソースがUTF-8または別のコードページの場合、これは問題を隠すだけです。 –

+0

あなたは_unknownエンコーディングでstd :: stringのパスから始めています。答えのコードサンプルは、その文字列のバイトファイルをstd :: wstringのwchar_t値にコピーします。 CreateDirectoryWは、wstringがUTF-16であることを想定しています。ソース文字列がASCIIまたはWindows-1252の場合、あなたの提案は(ほぼすべての場合)機能します。しかし、ソース文字列がUTF-8やWindows-1250のような別のエンコーディングにある場合、wstringにはナンセンスが含まれます。すべての場合に機能するようにするには、ソースからwstringに変換する(コピーではない)ソースコードを知る必要があります。 –

+0

いいえ、それは私が意味するものではありません。それは何が起こるかではありません。元の文字列にUTF-8としてエンコードされたギリシャ語の大文字のベータが含まれているとします。したがって、ソース文字列は '0xCE 0x92'です。ワイド文字列を作成する方法は、 '0x00CE 0x0092'を含んでいます。これは、ラテン大文字Iであり、サーカンフレックスとそれに続く私用文字が続きます。これは、コンバージョンの代わりにコピーを作成したためです。私の答えは変換を行う方法(ソースエンコーディングを知る必要がある)を説明し、実際のコード例を持つページへのリンクを持っています。 –

1

他の説明が正しい:

CreateDirectory、ウィンドウのAPIの多くのように、実際UNICODEが定義されているかどうかに応じて「ANSI」または「ワイド」バージョンに展開されるマクロです。 ANSIバージョンは、1バイト文字列を効果的にワイド文字列に変換し、ワイド文字列バージョンに委譲します。

しかし、直接いくつかの欠点が付属してCreateDirectoryAを呼び出すための提案:「ANSI」のAPIによって行わ

変換は、元の文字列は、ユーザーの現在のコードページでエンコードされていることを前提としています。単純なケースでは、これは本当らしいです。しかし、実生活のコードでは、そうではありません。だから間違ったタイプの変換で終わることがあります。これは後で見つかるバグにつながります。少なくとも悪い型変換はすぐに見つかるバグにつながります。

もっと良い解決策は、幅広い文字列(std :: wstring)を使い、CreateDirectoryWを呼び出すことです。間違った変換はありません。必要な型キャストはありません。

多くのコードベースでは、ワイド文字列を使用するためにすべてを書き直すことは現実的ではありません。正反対のことをし、std :: stringsを引き続き使用するが、標準化するためにはhold UTF-8 textという理由があることが判明しました。次に、Windows APIを呼び出す必要があるときは、(型変換ではなく)UTF-16に変換し、ワイドバージョンのAPIを直接呼び出します。これは、いくつかの変換といくつかの一時的なバッファを実行するコストを完全に忠実にします。これらの種類のコールはホットスポットになることはめったにないため、通常はコストがかかりません。

Windowsでは、UTF-8とUTF-16の間で変換するには、コードページをCP_UTF8に設定してMultiByteToWideChar/WideCharToMultiByteを呼び出すことができます。

0

私はかなりの間これを苦労しました。かなり掘り下げた後、私はこれが最もうまくいくことを発見しました。以下を試すことができます:

std::string t = "xyz"; 
CA2T wt (t.c_str());