std::stringをconst char*やchar*に変換するには?

std::stringcharconst char` に変換するにはどうしたらいいですか?

ソリューション

もし、std::string`const char*を必要とする関数に渡したいだけなら、次のようにします。

std::string str;
const char * c = str.c_str();

char *` のような書き込み可能なコピーを取得したい場合は、これでできます。

std::string str;
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0'; // don't forget the terminating 0

// don't forget to free the string after finished using it
delete[] writable;

編集。上記は例外セーフではないことに注意してください。newの呼び出しとdeleteの呼び出しの間で何かがスローされた場合、何も自動的にdelete`を呼び出してくれないので、メモリをリークしてしまいます。これを解決するには2つの方法があります。

boost::scoped_array

boost::scoped_arrayは、スコープ外に出たときに、あなたに代わってメモリを削除します。

std::string str;
boost::scoped_array writable(new char[str.size() + 1]);
std::copy(str.begin(), str.end(), writable.get());
writable[str.size()] = '\0'; // don't forget the terminating 0

// get the char* using writable.get()

// memory is automatically freed if the smart pointer goes 
// out of scope

std::vector

これは標準的な方法です(外部ライブラリを必要としません)。メモリを完全に管理してくれる std::vector` を使用します。

std::string str;
std::vector writable(str.begin(), str.end());
writable.push_back('\0');

// get the char* using &writable[0] or &*writable.begin()
解説 (33)

与えられた言葉は...

std::string x = "hello";

`string` から `char *` または `const char*` を取得する

。 **`x` がスコープ内にあり、さらに変更されない限り有効な文字ポインタを取得する方法**。 **C++11**では、以下のようにすべてが同じ内部文字列バッファにアクセスできます。
const char* p_c_str = x.c_str();
const char* p_data  = x.data();
char* p_writable_data = x.data(); // for non-const x from C++17 
const char* p_x0    = &x[0];

      char* p_x0_rw = &x[0];  // compiles iff x is not const...

上記のすべてのポインタは、バッファ内の最初の文字のアドレスという 同じ値 を保持します。 C++11 では、明示的に割り当てられた文字列内容の後に、常に余分な NUL/0 終端文字を保持することが保証されているため、空の文字列であっても「バッファ内の最初の文字」が存在します(例えば、std::string("this\0that", 9) は、"this\0that\0" を保持するバッファを持ちます)。 上記のポインターのいずれかが与えられると


char c = p[n];   // valid for n 
解説 (1)

const char *には.c_str()` メソッドを使用します。

char *のポインタを取得するために&mystring[0]` を使用することができますが、いくつかの問題があります: 必ずしもゼロ終端の文字列を取得できるわけではないことと、文字列のサイズを変更できないことです。また、文字列のサイズを変更することはできません。特に、文字列の最後に文字を追加しないように注意しなければなりません。そうしないと、バッファオーバーラン(およびクラッシュの可能性)が生じます。

C++11 までは、すべての文字が同じ連続したバッファの一部であるという保証はありませんでしたが、実際には、すべての既知の std::string の実装がそのように動作しました。Does "&s[0]" point to contiguous characters in a std::string?を参照してください。

多くの string メンバ関数は、内部バッファを再割り当てし、保存していたポインタを無効にすることに注意してください。すぐに使用してから破棄するのがベストです。

解説 (5)