2

'\0' 文字を保持しながら std::string を LPCSTR に変換するにはどうすればよいですか?

フィルターに区切り文字として '\0' を含める必要がある OPENFILENAME.lpstrFilter で結果を使用したいと考えています。

std::string.c_str() は '\0' を削除してトリムするようです

前もって感謝します!

==========================

(フォーラムの返信投稿のように、応答にコメントを適切に追加するにはどうすればよいですか?)

あなたのコメントを読んだ後、私はこのスニペットを再確認しました:

std::string filter = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0";
const char* f1 = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0";
const char* f2 = filter.c_str();
for(int i = 0; i < 50; i++)
{
 char c1 = *(f1 + i); // works
 char c2 = *(f2 + i); // doesn't work. beyond the first \0, it's garbage.
}

c_str() または LPCSTR の仕組みを間違えていますか?

4

4 に答える 4

6

C_STR は NUL 文字を削除しません。エラーは、STD::string の作成方法にある可能性があります。

于 2010-10-08T13:51:31.883 に答える
5

一般的に、std::stringは埋め込まれた「\0」文字を正しく処理します。

ただし、const char *とのインターフェースをとる場合は、細心の注意を払う必要があります。

この場合、問題は次の文字列の作成中にすでに発生しています。

std::string filter = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0"; // wrong

ここでは、constchar*からstd::stringを作成します。コンストラクターは、std :: stringの作成に使用する文字数を認識していないため、最初の「\0」で停止します。

文字を1つずつコピーすることもできますが、より良い方法があります。char配列に2つのイテレータを必要とするコンストラクタを使用します。1つは開始、もう1つは終了です。

const char filter_[] = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0"; 
std::string filter(filter_, filter_ + sizeof(filter_));

ひどいように見えますが、コードでこれを頻繁に行わないことを願っています。

更新:またはbegin()およびend()テンプレートの適切な定義(James Kanzeのコメントによる):

const char filter_[] = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0"; 
std::string filter(begin(filter_), end(filter_));
于 2010-10-08T14:48:26.517 に答える
2

埋め込まれた文字を含めるように最初に適切に構築されていれば、すべての文字が含まれていることを確認するために使用する必要がありlength()ます。string\0

スコープ内にあるLPCSTR間有効な場合:cString

#include <boost/scoped_array.hpp>
#include <string>
#include <algorithm>

string source("mystring");
boost::scoped_array<char> cString(new char[source.length() + 1]);

std::copy(source.begin(), source.end(), cString.get());
cString[source.length()] = 0;

LPCSTR rawStr = cString.get();

scoped_arrayなし:

#include <string>
#include <algorithm>

string source("mystring");
LPSTR rawStr = new char[source.length() + 1];

std::copy(source.begin(), source.end(), rawStr);
rawStr[source.length()] = 0;

// do the work here

delete[] rawStr;

編集:あなたのfilterinitでは、のコンストラクターは最初の文字stringまでのデータのみを含みます。\0これは理にかなっています-手元にあるのがデータのコピーだけであるのに、他にどのようにデータのコピーを止めないのでしょうconst char *か?これを試してみてください:

const char f3[] = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0";
std::string filter(f3, sizeof(f3));
于 2010-10-08T13:53:05.847 に答える
1

std::string のその後のライフサイクルに依存します。

たとえば、端末ゼロを手動で追加できます。

std::string test("init");
test += '\0';

これにより、長さが 1 増加します。または、ゼロを追加して std::string の別のインスタンスを作成するだけです

于 2010-10-08T13:49:48.333 に答える