2009-04-17 15 views
14

std :: stringには、c_str()のようなデータをフェッチするconstメンバーしかありません。しかし、私はoperator[]経由で文字列の最初の要素への参照を取得することができ、私はそれに書き込むことができます。例えばstd :: stringに書き込むことはできますか?

、私が機能している場合:

void toupper(char *first,char *last_plus_one); 

を、私は最初の要素へのポインタを取得し、ベクターに直接書き込むことができます。

vector<char> message // has "Some Message"; 
toupper(&message[0],&message[0]+message.size()); 

私はSTDと同じことを行うことができます::文字列?

string message="Some Message"; 
toupper(&message[0],&message[0]+message.size()); 

標準でメモリの位置が実際に線形であることが保証されていますか?すなわち:

&(*(message.begin()+n)) == &message[n] 

ありがとう。

+0

あなたは、単に文字列のイテレータを使用することができTOUPPER機能をテンプレート化することはできません小文字に変換する文字列「s」を考えますポインタの代わりに? – jalf

+0

もし私が私に聞くことはできませんでした。私は、ユニコードやその他のものをサポートしているかもしれない大きな第3回のparyライブラリを持っていると考えてください。そして、それらのAPIはポインタで動作します。テンプレートとしてこれを実装するのは単なるコストだからです。 – Artyom

+0

@ jalf:スタンダードは手元にありませんが、std :: to_upperはまさにあなたが提案しているものと信じています。 –

答えて

17

std :: stringには、新しいC++ 0x標準で連続したストレージが必要です。現在、これは未定義の動作です。

+7

不連続文字列を使用する既知のコンパイラはありますか? I.私は常に99%のケースで関連付けることができます(特定のコンパイラでコピーオーバヘッドを回避するための回避策があります) – Artyom

+6

私はいつも「きちんとした」と思っていました。これらのタイプのもの。それでも、コンプライアンス中は、ハード/非効率的/予期せぬことが起こります。 –

+0

@ダン:私はDinkumwareとSTLportの両方で、あらゆる種類のクライアントの非準拠の問題を捉えた(そして警告メッセージを出す)デバッグSTLを持っていると思います。しかし、私は間違ったことを覚えているかもしれません。 –

-1

私はそれがあなたに未定義の動作を与えると思います。書き込みにはstringstreamを使用し、str()メンバを使用してストリームの文字列を取得します。

+1

間違っています。文字列に書き込むことができます。 –

22

ハーブサッターが言うには、この(http://herbsutter.wordpress.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/#comment-483)があります。

現在のISO C++ [0]は連続した文字列データへのポインタまで咳を& STRを必要としないので、(必ずしもNULL終端されていません!)とにかく、連続していない文字列を持つ実装者の余裕はあまりありませんでした。 C++ 0xでは、std :: stringの内容を実際に連続して格納する必要があるという保証を既に採用しています。詳細については、http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530

を参照してください。Matt Auststeernは、参照先のドキュメント(http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530)に似ています。

これで、str [0]を呼び出すと、変更可能な文字配列を得ることができると思われます(ただし、nullで終了する必要はありません)。

+0

実際に私が見るリンクからC++ 03は連続メモリを必要としませんが、実際には他の実装はありません。 – Artyom

+0

私はSutterを疑うよりもよく知っていますが、誰かが&str [0]への参照を持って連続データへのポインタを生成する必要がありますか? – jalf

+1

Austernによると、演算子[]を介してアクセスすると、連続した配列が必要になります。反復子を介してアクセスすることはできません(str.begin()はそうではありません)。私はSutterやAusternを嫌うとは言いませんが、私はまだ自分には自信がありませんでしたので、私は "だから、そうだ"と言います。 –

5

はい、文字列を変更できます。

イテレータを使用するアルゴリズムでも使用できます。

ベクトルが<>と同じように使用することはできません。要素が連続したメモリ位置にあるという保証はありません(まだ近くの標準に来る)。

ポインタではなくイテレータを使用するようにアプローチを変更した場合、それはうまくいくはずです。イテレータはポインタのように動作するため、コードの変更は無視してください。

3

指摘されているように、イテレータを使用するアルゴリズムでは文字列を使用できます。同じケースがstd::transform例を使用して実装することができます: - :

int (*pf)(int)=tolower; //lowercase 
std::transform(s.begin(), s.end(), s.begin(), pf); 

よろしく、

関連する問題