char*型の文字列ポインタであれば、単純に値をコンストラクタに渡すだけで文字列変換が行えますが、char型単体やchar配列からの変換については少しだけやり方が異なります。
目次
const char* → 文字列
const char* → 文字列 (C++14)
char[] → 文字列
char → 文字列
to_stringは使えない
char* → std::string
string型(basic_string)のコンストラクタは、デフォルトで文字列ポインタからの変換に対応しています。
const char *cstr = "abc";
std::string str = std::string(cstr);
他にも、基本的なコンストラクタ呼び出しの方法に加えて、代入記法や統一初期化記法による変換も可能です。
const char *cstr = "abc";
std::string str(cstr); // コンストラクタ呼び出し
std::string str{cstr}; // 統一初期化(Uniform initialization)
std::string str = cstr; // 暗黙のコンストラクタ呼び出し & 初期化
std::string str; // デフォルトコンストラクタ呼び出し
str = cstr; // 暗黙のコンストラクタ呼び出し & コピー代入
暗黙的なコンストラクタ呼び出しは、関数呼び出し時の実引数内や戻り値を返す際にも行われるため、いずれも明示的な変換は不要です。
std::string fn(std::string s) {
char cary[] = {'a', 'b', '\0'};
return cary; // 明示的な変換は不要
}
int main() {
const char *cstr = "abc";
fn(cstr); // 明示的な変換は不要
}
std::string → const char*
逆にstd::string
からconst char*
に変換する場合はstd::string型のメンバ関数c_str()
を呼び出します。
std::string str("abc");
const char* cstr = str.c_str(); // "abc"
c_str関数の戻り値の有効期限はstring型オブジェクトの生存期間に依存するため、場合によってはc_str()
の結果をコピーする必要があります。以下のページを参考にしてください。
std::stringをcharに変換/コピーする方法【文字列 → char, char[], char*】
const char* → std::string (C++14)
C++14環境であれば、std::basic_string用の特殊なリテラルを利用することが可能です。
文字列リテラルに対してサフィックスs
を指定することで、string型への変換が行われます。
using namespace std::literals::string_literals;
std::string str = "foo"s; // std::string型のリテラル
std::string str = "foo"s + "bar"; // C言語文字列との結合も可能
std::wstring b = L"b"s; // ワイド文字列
std::u16string c = u"c"s; // UTF-16
std::u32string d = U"d"s; // UTF-32
C言語スタイルの文字列ポインタとの結合も行えるため、非常に便利に使えます。
char[] → std::string
char配列の場合は配列のサイズを指定する必要があります。
char cary[] = {'a', 'b', 'c'};
std::string str(cary, 3); // "abc"
char → std::string
char型単体での変換を行う場合には初期化リストを用いる必要があります。
char ch = 'a';
std::string a{ch}; // "a"
std::string b = {'b'}; // "b"
std::string c = {ch, 'b', 'c'}; // "abc"
初期化リストによる変換はC++11から行えるようになったものであり、古いコンパイラでは利用出来ない場合があります。
あまりオススメはしませんが、空文字との結合テクニックもあります。
auto a = std::string() + 'a'; // "a"
auto b = ""s + 'b'; // "b" (C++14)
また特殊なコンストラクタを利用する方法もあります。
char ch = 'a';
std::string str(1, ch); // "a"
以下のコンストラクタを呼び出しています。
// Construct string as multiple characters.
// @n Number of characters.
// @c Character to use.
// @a Allocator to use (default is default allocator).
basic_string(size_type n, _CharT c, const _Alloc& a = _Alloc());
// Samples
std::string str(1, 'a'); // "a"
std::string str(2, 'a'); // "aa"
通常のコンストラクタを用いた方法ではエラーになりますので注意してください。
// No matching conversion for functional-style cast from 'char' to 'std::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >')
std::string a = std::string('a');
// No matching constructor for initialization of 'std::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >')
std::string b('a');
// No viable conversion from 'char' to 'std::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >')
std::string c = 'a';
std::to_stringは使えない
char型単体の値を文字列型に変換する際にstd::to_string()
を使おうとするとstd::to_string(int val)
が呼ばれてしまいますので注意してください。
std::to_string(char val)
は未定義であり、代わりに暗黙の型変換によってint版のto_stringが呼ばれてしまいます。
以下のように、char型に対応したto_string関数を独自に作成すると良いかもしれません。
namespace you {
std::string to_string(char val) {
return std::string(1, val);
// return std::string{val};
}
}
char c = 'c';
auto s = std::to_string(c); // "99"
auto s = you::to_string(c); // "c"
配列サイズの指定方法と注意点
配列サイズは自身の利用シーンに合わせて適切に指定する必要があります。参考までにcary
配列の宣言と同一スコープ内に限り、以下ようにsizeof
キーワードによる静的な配列サイズを取得することが可能になります。
const char cary[] = {'a', 'b', 'c'};
size_t sizeOfAry = sizeof(cary) / sizeof(cary[0]); // 3 = 3 / 1
std::string str(cary, sizeOfAry); // "abc"
char
型は1バイトなのでsizeof(cary) / sizeof(cary[0])
はsizeof(cary)
としても問題ありませんが、wchar_t
やchar16_t
,char32_t
を扱う場合は先程の計算式を用いるようにしてください。
const char16_t cary[] = {'a', 'b', 'c'};
size_t sizeOfAry = sizeof(cary) / sizeof(cary[0]); // 3 = 6 / 2
std::u16string str(cary, sizeOfAry); // "abc"
固定長配列や動的配列の要素数を求める方法とその詳細については以下のページが参考になります。
配列の要素数を求める方法と注意点
ピンバック: 【C++】stringをcharに変換/コピーする色々な方法【値 配列 ポインタ】 | MaryCore
ピンバック: 【C++】数値型をstring型に変換する複数の方法【int/double to string】 | MaryCore