2012-04-11 10 views
4

read()にstd :: stringを使用することはできますか?read()にstd :: stringを使用することはできますか?

例:

std::string data; 

read(fd, data, 42); 

Normalyは、我々は、char *を使用する必要がありますが、それは直接のstd ::文字列を使用することは可能でしょうか?読み取り機能はありません、その後、、char *を必要とする場合

感謝の

+0

ゼロコピーがあなたの目標であれば、 "read"を "mmap"に置き換え、それに固定割り当てのstd :: stringをラップするのに役立ちますか? – user1202136

+0

あなたが読んでいる文字列に空白がありますか? –

答えて

7

機能には何らかの形で、char*を作成する必要があります。 (?ところで:std::istream::readあなたは、Posixの機能 readについて話しているあなたではない、としない)問題が char*ではない、それは(私はあなたが実際に何を意味するのか である疑いがある)に何char*ポイントです。

ここで最も単純かつ通常の解決策は、ローカル配列を使用することです:

char buffer[43]; 
int len = read(fd, buffer, 42); 
if (len < 0) { 
    // read error... 
} else if (len == 0) { 
    // eof... 
} else { 
    std::string data(buffer, len); 
} 

あなたはstd::stringに直接取り込みたい場合は、しかし、これが可能 (良いアイデア必ずしも必要ではないが)です。

std::string data; 
data.resize(42); 
int len = read(fd, &data[0], data.size()); 
// error handling as above... 
data.resize(len); // If no error... 

これはコピーを避けますが、率直に言って...コピーは、実際の読み取り用と 割り当てOのために必要な時間に比べ 重要ではありませんf文字列のメモリ。これは実際に読み取られる文字に必要な最小値である ではなく、実際のバッファーが42バイト(切り上げられたもの)になるような結果の文字列の(おそらく )無視しています。

(そして、人々は時々std:;stringにおけるメモリの 連続性に関して、問題を提起するので:これは、10以上の 年前の問題でしたstd::stringの元の仕様は非連続許可するexpressedly を設計しました。実際には実装者はこの が有用であると判断し、人々は連続性を前提としていました。どの時点で、 標準委員会は、基準を既存の の実務に合わせることを決定し、連続性を要求しています。したがって、 は連続していません。また、今後の実装では、C++ 11の要件を満たしている連続したものは存在しません。

+0

"これはコピーを避けますが、率直に言って...コピーは実際の読み込みに必要な時間と比較して重要ではありません。文字列内のメモリ。読み取るデータのサイズによって異なります。人々はLinuxカーネルをいくつかのデータ転送経路でゼロコピーにするためにかなりの努力を払っていました。 – user1202136

+0

@ user1202136この場合、コピーのサイズは42バイトです。動的割り当てと、システムからのバイトの転送があります。状況は、バッファ(少なくとも4KB以上で、プールから割り当てられる可能性が高い)のようなものを扱うときは、少なくともカーネルでは異なります。 –

0

(私は店結果のため、char *を作成しないことを好みます)。最初にサイズを変更されている限り、charのstd :: vectorの最初の要素のアドレスを使用できます。私は古い(pre C++ 11)の文字列が連続したメモリを持つことを保証していないと思います。そうでなければ、文字列と同様のことをすることができます。

0

いいえ、あなたはできません。しないでください。通常、std :: stringの実装では、割り当てられたメモリのサイズや実際の文字列の長さなど、他の情報が内部的に格納されます。 C++ドキュメントには、c_str()またはdata()によって返される値を変更すると、定義されていない動作が発生することが明示的に記載されています。

0

ありませんが、

std::string data; 
cin >> data; 

だけで正常に動作します。 read(2)の振る舞いを本当にしたい場合は、独自のバッファーを割り当てて管理する必要があります。

+0

これは空白を打ち破ります。 –

+2

質問からわかるように、 – DRVic

0

read()は生データ入力用ですので、 stringは実際には悪い選択です。std :: stringはテキストを処理するためです。 std :: vectorは生データを扱う正しい選択のようです。

-1

ストリングライブラリからstd :: getlineを使用すると(cplusplus.com参照)、ストリームから読み込んで直接文字列オブジェクトに書き込むことができます。例(再びcplusplus.comからリッピング - 第一は、getlineのためにGoogleでヒット):標準入力(CIN)から、ファイル(はifstream)からの読み取り時

int main() { 
    string str; 
    cout << "Please enter full name: "; 
    getline (cin,str); 
    cout << "Thank you, " << str << ".\n"; 
} 

だから動作します。

+0

これはなぜ関連していますか? readはposixのシステムコールであり、コンソールインには関係しません。 –

関連する問題