- ベストアンサー
C/C++関数間でのStringクラスの扱い
以下のようなコードを実行してみましたが思い通りに動いてくれません. "sample"という文字列がstrへとコピーされると思ったのですが. stringクラスのc_str()メソッドはconst char*だと言っているので無理矢理キャストしたのが原因でしょうか.stringクラスは記憶領域を自動で変更してくれるのではないのですか.それともこの挙動は仕様ですか. -------- 以下コード -------- #include <iostream> #include <string> using namespace std; int func(char *); int main(void) { string str(""); func((char *)str.c_str()); cout << "String: " << str << endl; return EXIT_SUCCESS; } int func(char *buf) { buf = "sample"; return 0; } -------- 以上コード --------
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
> func((char *)str.c_str()); c_str()がstringの内部バッファをそのまま返すことは保証されていません。 だから func(&str[0]) が正解。
その他の回答 (5)
- koko_u_
- ベストアンサー率18% (459/2509)
>実はこのコード自体は抽象化したコードで, >func()にあたる部分はAPI関数のために書き換えができない状況です 「抽象化」しすぎですが、そういった場合は素直に func() のインターフェイスに合わせて、string 型の変数の内容をいったん char 型の配列にコピーして func() を利用するのがよいと思います。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> ただstringクラスを利用できるのならば利用したいので string str = "...."; func(&str[0]); 注意: - strは十分な領域が確保されていること。 - func呼び出し後、strの後部にはゴミが残るので必要に応じて削除すべし。
補足
-------- 以下コード -------- #include <iostream> #include <string> using namespace std; int func(char *); int main(void) { string str(""); func((char *)str.c_str()); cout << "String: " << str << endl; return EXIT_SUCCESS; } int func(char *buf) { strcpy(buf, "sample"); return 0; } -------- 以上コード -------- ですね.これはこちらのミスでした.ついうっかりcharポインタでstringの記法を使ってしまいました. > - strは十分な領域が確保されていること。 > - func呼び出し後、strの後部にはゴミが残るので必要に応じて削除すべし。 やはりここがネックになるんですね.string str("AAAAAAAA");とでもするとその文字列の範囲ではうまくいくことを確認しています.(字数が少なかった場合はゴミが出たり,字数が多い場合は途中で切れたりしますが.)
- mesoneer
- ベストアンサー率20% (2/10)
func((char *)str.c_str()); の呼び出しで (char *)str.c_str() の内容はコピーされて func関数の引数である buf に渡されます。 つまり、(char *)str.c_str()とbufの指し示すアドレスは同じですが、 (char *)str.c_str()とbufが保持されているメモリ領域は別です なので、func関数内でbufを書き換えても(char *)str.c_str()には反映されません やるとしたら、bufが指し示す内容を書き換えるのがいいかと思います strcpy(buf, "sample"); のような感じで。 ただ、stringは内部に現在の文字列の長さなどの情報を持っているので、文字列を書き換えただけではいろいろと不都合が起こってしまいます。 stringを使った場合は、素直にstringに渡すという形で、 int func(string& str) { str = "sample"; return 0; } の様にするのがベストだと思います。
補足
3人もの方から解答をいただきありがとうございます.実はこのコード自体は抽象化したコードで,func()にあたる部分はAPI関数のために書き換えができない状況です.ただstringクラスを利用できるのならば利用したいので解決策があればご教授願います.実際のコードは以下です.(stringではなくcharポインタだと正しく動作します.) --------------------- string buffer(""); (中略) recv(clSocket, (char*)buffer.c_str(), buffer.size(), 0); cout << "Buffer: " << buffer << endl;
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> "sample"という文字列がstrへとコピーされると思ったのですが. いいえ、コピーされません。 ↓ 相手がstringでなくても正しく動きません。 #include <iostream> int func(char* buf) { buf = "sample"; return 0; } int main() { char str[] = "hello, world"; func(str); std::cout << str; }
- koko_u_
- ベストアンサー率18% (459/2509)
>"sample"という文字列がstrへとコピーされると思ったのですが. 1. int func(char* buf) は「何もしない」関数になっています 2. str.c_str() の戻すポインタの指す場所に書き込んではいけません string str("sample"); でよろしかろう。
お礼
すみません.ご連絡が遅れました. そうですね.そうすることにします. みなさんありがとうございました.