[解決済み] stringstream, string, char* 変換の混乱
質問
私の質問は、以下のように要約できます。
stringstream.str().c_str()
から返された文字列はメモリ上のどこにあるのか、そしてなぜそれが
const char*
?
このコード例は、私よりもうまく説明してくれるでしょう。
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
stringstream ss("this is a string\n");
string str(ss.str());
const char* cstr1 = str.c_str();
const char* cstr2 = ss.str().c_str();
cout << cstr1 // Prints correctly
<< cstr2; // ERROR, prints out garbage
system("PAUSE");
return 0;
}
という前提で
stringstream.str().c_str()
を割り当てることができました。
const char*
はバグを引き起こし、それを追跡するのにしばらくかかりました。
ボーナスポイントとして、なぜ
cout
という文に置き換えた理由を説明できる人はいますか?
cout << cstr // Prints correctly
<< ss.str().c_str() // Prints correctly
<< cstr2; // Prints correctly (???)
は文字列を正しく表示しますか?
Visual Studio 2008でコンパイルしています。
どのように解決するのですか?
stringstream.str()
は一時的な文字列オブジェクトを返し、完全な式の終了時に破棄されます。もし、そこからCの文字列へのポインタを得ると(
stringstream.str().c_str()
) から C の文字列へのポインタを得ると、それは文が終わったところで削除される文字列を指すことになります。これが、あなたのコードがゴミを表示する理由です。
その一時的な文字列オブジェクトを他の文字列オブジェクトにコピーして、そこからCの文字列を取り出すことができます。
const std::string tmp = stringstream.str();
const char* cstr = tmp.c_str();
なお、一時的な文字列を
const
に変更すると再割り当てされる可能性があるためです。
cstr
を無効にしてしまうからです。の呼び出しの結果は保存しない方が安全です。
str()
を呼び出した結果を全く保存せず
cstr
を使い、完全な式の終わりまでしか使いません。
use_c_str( stringstream.str().c_str() );
もちろん、後者は簡単ではないかもしれませんし、コピーにはコストがかかりすぎるかもしれません。その代わりにできることは、一時的なものを
const
参照にバインドすることです。これによって、その寿命は参照の寿命まで延長されます。
{
const std::string& tmp = stringstream.str();
const char* cstr = tmp.c_str();
}
IMOはそれが最良の解決策だと考えています。残念ながらあまり知られていないのですが。
関連
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] バイトを文字列に変換する
-
[解決済み】JavaScriptで文字列の出現箇所をすべて置換する方法
-
[解決済み】大文字・小文字を区別しない「Contains(string)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】'cout'は型名ではない
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない