1

バッファオーバーフローが心配なので、std::istreamから派生したクラスからいくつかの文字を取得する必要があります。私が理解していることから、私自身の>>演算子がなければ、istreamから直接std::stringにストリーミングする方法はありません。そのため、コンテンツをchar配列にストリーミングし、それをstd::stringに入れることを検討していました。簡単な例を次に示します。

char CharArray[1000] = {0};
SomeIStream >> CharArray;
std::string StuffFromStream(CharArray);

ただし、CharArrayがオーバーフローしないことを知る方法はないようです。ストリーム抽出演算子がchararrayに書き込む最大値はありますか?先制的に抽出される量を確認する方法はありますか?これはすべて間違っていますか、これよりもはるかに優れた方法はありますか?

Edit1 :、メモリリークではない問題を修正しました。削除を呼び出す必要はありません。信じられない。

Edit2:文字列に直接>>を使用する提案が提案されました。以前のコードベースでこの問題が発生したことを試みましたが、失敗しました。オペレーターに適した一致が見つからなかったと言っています。次に、std :: fstreamを試してみましたが、再び失敗しました。単純なミニマルプロジェクトでstd::fstreamコードを試すことに成功しました。これは、私のより大きなプロジェクトに何か他の問題があることを示しています。この質問の本来の意図はもはや有効ではありません。

Edit3:私はこれを解決しました。私はtypedefStringにストリーミングしようとしましたが、これは実際にはstd :: stringだと思っていましたが、実際にはconst std::Stringでした。当然、書き込み不可能なオブジェクトに書き込むためのストリーム抽出演算子はありません。そのため、istreamヘッダーにリストされているすべての演算子が表示されます(必要な演算子は文字列ヘッダーにあります)。

私の誤った研究を指摘し、正しい方向に私を向けてくれた人々に感謝します。

4

5 に答える 5

3

std :: istreamから(適切に)継承している場合は、特別なことをする必要はなく、を使用するだけoperator >> (std::istream&, std::string&)です。

std::string s;
SomeIStream >> s;

「適切に」とは、istreamから適切な仮想関数をオーバーライドすることを意味します。

「削除する前に例外があると、メモリリークが発生することを私は知っています。」いいえ、そうではありません。で割り当てませんでしCharArraynew; それを呼び出すdeleteことはあなたが望むことをしません。

于 2010-12-15T21:36:30.137 に答える
0

昔ながらのCスタイルのchar配列とストリームを混在させますか?非常に混乱したコードのようです。

解説はさておき、文字列に直接抽出するだけです。これを(メソッドを介してc_str())パラメーターを期待するCスタイルのAPIに渡すことができconst char*ます。また、奇妙な理由で実際にchar配列が必要な場合は、境界を確認した後、からchar配列に安全に移動できcopyますstring

ちなみに、あなたは魔法数が邪悪である主な方法をかなり明確に示しています。あなたの場合、問題のマジックナンバーはです1000。完全に推測することなく、適切であるかどうか1000(大きすぎず、小さすぎない)はわかりません。プログラミングでは、推測はしばしば==クラッシュします。またはさらに悪いことに、クラッシュしません。

ちなみに、delete上記の自動変数を使用しています。あなたはこれをしません。を使用するdelete場合にのみ使用してくださいnew。あなたはしなかったnewので、しないでくださいdelete

ちなみに、ストリーム全体を文字列に抽出するだけの場合は、次のようにすることができます。

string s = SomeIStream.str();
于 2010-12-15T21:33:05.550 に答える
0

すべてのストリームは.str()メソッドを提供します。このメソッドは、バッファーのコピーをstd :: string(またはwstringなど、他のtypedefの場合は何でも)として提供します。

また、スタック上で配列を宣言してから、それを削除しようとしました。これはUBです。

于 2010-12-15T21:36:28.487 に答える
0

ストリーム全体を文字列に読み込みたい場合、これはそれほど効率的ではありませんが、安全です。

std::string str((std::istream_iterator<char>(some_istream)), std::istream_iterator<char>());

(最も厄介な解析を避けるために、余分な括弧に注意してください)

「n」文字まで読みたい場合:

some_istream.read(some_char_array, sizeof(some_char_array));

これは配列をnullで終了しないことに注意してください。sizeof(char_array) - 1配列の最後の文字をそのままにしておきたい場合は、代わりにパスします。

于 2010-12-15T21:40:07.670 に答える
0

これが私のアプローチです(ブルース・エッケルの「Thinking in C ++」から)::

ifstream in( "somefile.txt"、ios :: in);
istreambuf_iterator istr(in)、end;
文字列str;
insert_iterator ins(str、str.begin());

while(istr!= end){
      * ins ++ = * istr ++;
}

上記のコードでは、ファイル全体が文字ストリームとして取得され、文字列に入れられます。これは単なる例として示されています。

于 2010-12-16T03:55:23.447 に答える