C++
std :: string
サーチ…
前書き
文字列は、文字列を表すオブジェクトです。標準のstring
クラスは、テキストや他の文字のシーケンスを処理する際に、 char
の明示的な配列を使用することに代わって、シンプルで安全で多目的な代替手段を提供します。 C ++ string
クラスはstd
名前空間の一部であり、1998年に標準化されました。
構文
//空文字列宣言
std :: string s;
// const char *(c-string)からの構築
std :: string s( "こんにちは");
std :: string s = "こんにちは";
//コピーコンストラクタを使用して構築する
std :: string s1( "Hello");
std :: string s2(s1);
//部分文字列から構築する
std :: string s1( "Hello");
std :: string s2(s1、0、4); // s1の位置0からs2に4文字をコピーする
//文字のバッファから構築する
std :: string s1( "Hello World");
std :: string s2(s1、5); // s1の最初の5文字をs2にコピーする//フィルコンストラクタを使用して構築する(charのみ)
std :: string s(5、 'a'); // sにはaaaaaが含まれています
//範囲コンストラクタとイテレータを使用して構築する
std :: string s1( "Hello World");
std :: string s2(s1.begin()、s1.begin()+ 5); // s1の最初の5文字をs2にコピーする
備考
std::string
を使用する前に、他のヘッダー( iostream
)には含まれていない関数/演算子/オーバーロードが含まれるため、ヘッダーstring
を含める必要があります。
nullptrでconst char *コンストラクタを使用すると、未定義の動作につながります。
std::string oops(nullptr);
std::cout << oops << "\n";
at
のメソッドat
、 index >= size()
場合にstd::out_of_range
例外at
スローします。
operator[]
の動作は少し複雑です。すべての場合、 index > size()
場合は未定義の動作をしindex > size()
が、 index == size()
場合は動作しません。
- 非const文字列では、動作は未定義です。
- const文字列では、値が
CharT()
( ヌル文字)の文字への参照が返されます。
- 値
CharT()
( ヌル文字)を持つ文字への参照が返されます。 - この参照を変更することは未定義の動作です。
代わりに使用するC ++ 14は、 "foo"
、使用することをお勧めします"foo"s
のように、 s
あり、ユーザ定義リテラルサフィックス変換、 const char*
"foo"
するためにstd::string
"foo"
。
注意:リテラルs
を取得するには、 std::string_literals
またはstd::literals
std::string_literals
という名前空間を使用する必要があります。
分割
std::string::substr
を分割するにはstd::string::substr
を使用します。このメンバ関数には2つのバリエーションがあります。
最初の要素は、返された部分文字列の開始位置をとります。開始位置は、範囲(0, str.length()]
で有効でなければなりません:
std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(11); // "bar and world!"
2番目は、新しい部分文字列の開始位置と合計長をとります。 長さにかかわらず、部分文字列はソース文字列の最後を決して通過しません:
std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(15, 3); // "and"
あなたも呼び出すことができることに注意してください substr
引数なしで、この場合には、文字列の正確なコピーが返されます
std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(); // "Hello foo, bar and world!"
文字列の置換
ポジションで交換
std::string
一部を置き換えるには、 std::string
からreplace
メソッドを使用できstd::string
。
replace
には多くの便利なオーバーロードがあります:
//Define string
std::string str = "Hello foo, bar and world!";
std::string alternate = "Hello foobar";
//1)
str.replace(6, 3, "bar"); //"Hello bar, bar and world!"
//2)
str.replace(str.begin() + 6, str.end(), "nobody!"); //"Hello nobody!"
//3)
str.replace(19, 5, alternate, 6, 6); //"Hello foo, bar and foobar!"
//4)
str.replace(19, 5, alternate, 6); //"Hello foo, bar and foobar!"
//5)
str.replace(str.begin(), str.begin() + 5, str.begin() + 6, str.begin() + 9);
//"foo foo, bar and world!"
//6)
str.replace(0, 5, 3, 'z'); //"zzz foo, bar and world!"
//7)
str.replace(str.begin() + 6, str.begin() + 9, 3, 'x'); //"Hello xxx, bar and world!"
//8)
str.replace(str.begin(), str.begin() + 5, { 'x', 'y', 'z' }); //"xyz foo, bar and world!"
文字列の出現を別の文字列に置き換える
replace
の最初のオカレンスだけをstr
with with
replace
str
。
std::string replaceString(std::string str,
const std::string& replace,
const std::string& with){
std::size_t pos = str.find(replace);
if (pos != std::string::npos)
str.replace(pos, replace.length(), with);
return str;
}
置き換えのすべての出現をwith with
str
でreplace
str
。
std::string replaceStringAll(std::string str,
const std::string& replace,
const std::string& with) {
if(!replace.empty()) {
std::size_t pos = 0;
while ((pos = str.find(replace, pos)) != std::string::npos) {
str.replace(pos, replace.length(), with);
pos += with.length();
}
}
return str;
}
連結
オーバーロードされた+
と+=
演算子を使ってstd::string
を連結することができます。 +
演算子の使用:
std::string hello = "Hello";
std::string world = "world";
std::string helloworld = hello + world; // "Helloworld"
+=
演算子を使用する:
std::string hello = "Hello";
std::string world = "world";
hello += world; // "Helloworld"
文字列リテラルを含むC文字列を追加することもできます。
std::string hello = "Hello";
std::string world = "world";
const char *comma = ", ";
std::string newhelloworld = hello + comma + world + "!"; // "Hello, world!"
push_back()
を使って個々のchar
をプッシュバックすることもできます:
std::string s = "a, b, ";
s.push_back('c'); // "a, b, c"
append()
もありappend()
。これは+=
似ています。
std::string app = "test and ";
app.append("test"); // "test and test"
キャラクターへのアクセス
std::string
から文字を抽出するにはいくつかの方法があり、それぞれ微妙に異なります。
std::string str("Hello world!");
演算子[](n)
インデックスnの文字への参照を返します。
std::string::operator[]
は境界チェックされておらず、例外をスローしません。呼び出し元は、インデックスが文字列の範囲内にあることを主張します。
char c = str[6]; // 'w'
at(n)
インデックスnの文字への参照を返します。
std::string::at
は boundsをチェックし、インデックスが文字列の範囲内にない場合はstd::out_of_range
をスローします:
char c = str.at(7); // 'o'
注意:文字列が空の場合、これらの例のどちらも未定義の動作になります。
前面()
最初の文字への参照を返します。
char c = str.front(); // 'H'
バック()
最後の文字への参照を返します。
char c = str.back(); // '!'
トークン化
実行時に最も安いものから最も高価なものまでリストされています:
str::strtok
は標準で提供されるもっとも安価なトークン化メソッドであり、トークン間でデリミタを変更することもできますが、現代のC ++では3つの困難が伴います。-
std::strtok
は複数のstrings
で同時に使用することはできません(ただし、strtok_s
など、これをサポートするためにいくつかの実装が拡張されています) - 同じ理由から、
std::strtok
は複数のスレッドで同時に使用することはできません(これは実装定義されている可能性があります。例: Visual Studioの実装はスレッドセーフです ) -
std::strtok
を呼び出すと、操作中のstd::string
変更されるので、const string
s、const char*
、またはリテラル文字列では使用できません。これらをstd::strtok
でトークン化したり、std::string
の内容を保持する必要がある場合、入力をコピーしなければならず、次にコピーを操作する必要があります
一般的に、これらのオプションのコストはトークンの割り当てコストに隠されますが、最も安いアルゴリズムが必要で
std::strtok
の難しさが克服されない場合は、 手でスピンされたソリューションを検討してください。-
// String to tokenize
std::string str{ "The quick brown fox" };
// Vector to store tokens
vector<std::string> tokens;
for (auto i = strtok(&str[0], " "); i != NULL; i = strtok(NULL, " "))
tokens.push_back(i);
-
std::istream_iterator
は、ストリームの抽出演算子を繰り返し使用します。入力std::string
が空白で区切られている場合、std::strtok
オプションを拡張することができます。これにより、インライントークン化が可能になり、const vector<string>
生成がサポートされ、複数の白い文字を区切る:
// String to tokenize
const std::string str("The quick \tbrown \nfox");
std::istringstream is(str);
// Vector to store tokens
const std::vector<std::string> tokens = std::vector<std::string>(
std::istream_iterator<std::string>(is),
std::istream_iterator<std::string>());
-
std::regex_token_iterator
はstd::regex
を使って反復的にトークン化します。これは、より柔軟な区切り文字の定義を提供します。たとえば、区切り文字で区切られていないカンマや空白文字は次のようになります。
// String to tokenize
const std::string str{ "The ,qu\\,ick ,\tbrown, fox" };
const std::regex re{ "\\s*((?:[^\\\\,]|\\\\.)*?)\\s*(?:,|$)" };
// Vector to store tokens
const std::vector<std::string> tokens{
std::sregex_token_iterator(str.begin(), str.end(), re, 1),
std::sregex_token_iterator()
};
詳細については、 regex_token_iterator
例を参照してください。
(const)char *への変換
std::string
データへのconst char*
アクセスを取得するには、文字列のc_str()
メンバー関数を使用できます。ポインタは、 std::string
オブジェクトがスコープ内にあり、変更されていない限り、有効であることに注意してください。つまり、オブジェクトに対してconst
メソッドだけが呼び出される可能性があります。
data()
メンバー関数を使用して、 std::string
オブジェクトのデータを操作するために使用できる変更可能なchar*
を取得できます。
変更可能なchar*
は、最初の文字: &s[0]
アドレスを取得することによっても取得できます。 C ++ 11では、整形式のヌル終了文字列が生成されることが保証されています。なお、 &s[0]
としてもよく、形成されるs
空である、一方&s.front()
未定義であるs
空です。
std::string str("This is a string.");
const char* cstr = str.c_str(); // cstr points to: "This is a string.\0"
const char* data = str.data(); // data points to: "This is a string.\0"
std::string str("This is a string.");
// Copy the contents of str to untie lifetime from the std::string object
std::unique_ptr<char []> cstr = std::make_unique<char[]>(str.size() + 1);
// Alternative to the line above (no exception safety):
// char* cstr_unsafe = new char[str.size() + 1];
std::copy(str.data(), str.data() + str.size(), cstr);
cstr[str.size()] = '\0'; // A null-terminator needs to be added
// delete[] cstr_unsafe;
std::cout << cstr.get();
文字列内の文字の検索
文字や別の文字列を見つけるには、 std::string::find
使うことができstd::string::find
。最初の一致の最初の文字の位置を返します。一致するものが見つからない場合、関数はstd::string::npos
返します
std::string str = "Curiosity killed the cat";
auto it = str.find("cat");
if (it != std::string::npos)
std::cout << "Found at position: " << it << '\n';
else
std::cout << "Not found!\n";
見つかった位置:21
検索の機会は、次の機能によってさらに拡張されます。
find_first_of // Find first occurrence of characters
find_first_not_of // Find first absence of characters
find_last_of // Find last occurrence of characters
find_last_not_of // Find last absence of characters
これらの関数を使用すると、文字列の最後から文字を検索したり、文字列にない文字を検索したりすることができます。次に例を示します。
std::string str = "dog dog cat cat";
std::cout << "Found at position: " << str.find_last_of("gzx") << '\n';
見つかった位置:6
注意:上記の関数は部分文字列を検索するのではなく、検索文字列に含まれる文字を検索することに注意してください。この場合、位置6
最後の'g'
が出現しました(他の文字は見つかりませんでした)。
開始/終了時の文字のトリミング
この例では、 <algorithm>
、 <locale>
、 <utility>
というヘッダが必要です。
シーケンスまたは文字列をトリミングするとは、特定の述語に一致するすべての先頭および末尾の要素(または文字)を削除することを意味します。最初の要素は、要素を移動することを伴わないため、最初の要素をトリムし、先頭の要素をトリムします。以下の一般化はstd::basic_string
(例えばstd::string
とstd::wstring
)のすべての型で動作し、また誤ってシーケンスコンテナ( std::vector
やstd::list
)でも動作することに注意してください。
template <typename Sequence, // any basic_string, vector, list etc.
typename Pred> // a predicate on the element (character) type
Sequence& trim(Sequence& seq, Pred pred) {
return trim_start(trim_end(seq, pred), pred);
}
末尾の要素をトリミングするには、述語と一致しない最後の要素を見つけてそこから消去する必要があります。
template <typename Sequence, typename Pred>
Sequence& trim_end(Sequence& seq, Pred pred) {
auto last = std::find_if_not(seq.rbegin(),
seq.rend(),
pred);
seq.erase(last.base(), seq.end());
return seq;
}
先頭の要素をトリムするには、 最初の要素を見つけてその述語と一致しないものを探し出し、そこまで消去する必要があります。
template <typename Sequence, typename Pred>
Sequence& trim_start(Sequence& seq, Pred pred) {
auto first = std::find_if_not(seq.begin(),
seq.end(),
pred);
seq.erase(seq.begin(), first);
return seq;
}
std::string
空白をstd::isspace()
するために上記を特化するには、 std::isspace()
関数を述語として使用できます。
std::string& trim(std::string& str, const std::locale& loc = std::locale()) {
return trim(str, [&loc](const char c){ return std::isspace(c, loc); });
}
std::string& trim_start(std::string& str, const std::locale& loc = std::locale()) {
return trim_start(str, [&loc](const char c){ return std::isspace(c, loc); });
}
std::string& trim_end(std::string& str, const std::locale& loc = std::locale()) {
return trim_end(str, [&loc](const char c){ return std::isspace(c, loc); });
}
同様に、 std::wstring
などのためにstd::wstring
std::iswspace()
関数を使用できます。
トリムされたコピーである新しいシーケンスを作成する場合は、別の関数を使用できます。
template <typename Sequence, typename Pred>
Sequence trim_copy(Sequence seq, Pred pred) { // NOTE: passing seq by value
trim(seq, pred);
return seq;
}
辞書学的比較
2つのstd::string
は、演算子==
、 !=
、 <
、 <=
、 >
、 >=
を使って辞書的に比較できます。
std::string str1 = "Foo";
std::string str2 = "Bar";
assert(!(str1 < str2));
assert(str > str2);
assert(!(str1 <= str2));
assert(str1 >= str2);
assert(!(str1 == str2));
assert(str1 != str2);
これらの関数はすべて、基になるstd::string::compare()
メソッドを使用して比較を実行し、便利なブール値を返します。これらの関数の動作は、実際の実装に関係なく、次のように解釈される可能性があります。
演算子
==
:str1.length() == str2.length()
と各文字ペアが一致する場合はtrue
を返し、そうでない場合はfalse
返しfalse
。演算子
!=
:str1.length() != str2.length()
または1文字ペアが一致しない場合はtrue
返し、そうでない場合はfalse
返しfalse
。演算子
<
または演算子>
:最初の異なる文字ペアを検索し、それらを比較してブール結果を返します。
演算子
<=
または演算子>=
:最初の異なる文字ペアを検索し、それらを比較してブール結果を返します。
注: 文字ペアという用語は、同じ位置の両方の文字列に対応する文字を意味します。理解をstr2
にするために、2つの例文列がstr1
およびstr2
であり、その長さがそれぞれn
およびm
ある場合、両方の文字列の文字ペアは、それぞれstr1[i]
およびstr2[i]
対を意味し、 i = 0,1,2 ,. ..、max(n、m)である 。対応する文字が存在しないiの場合、すなわち、 iがn
またはm
以上でm
場合、それは最も低い値とみなされる。
次に、 <
:を使用する例を示します。
std::string str1 = "Barr";
std::string str2 = "Bar";
assert(str2 < str1);
手順は次のとおりです。
- 最初の文字を比較すると、
'B' == 'B'
- 移動します。 - 2番目の文字
'a' == 'a'
比較する - 移動する。 - 3番目の文字
'r' == 'r'
比較する - 移動する。 -
str1
範囲はまだ文字を持っていますが、str2
範囲は使い尽くされています。したがって、str2 < str1
。
std :: wstringへの変換
C ++では、文字のシーケンスは、 std::basic_string
クラスをネイティブ文字タイプで特殊化することによって表現されます。標準ライブラリで定義されている2つの主要コレクションは、 std::string
とstd::wstring
です。
std::string
はchar
型の要素で構築されていますstd::wstring
はwchar_t
型の要素で構築されています
2つのタイプを変換するには、 wstring_convert
使用しwstring_convert
。
#include <string>
#include <codecvt>
#include <locale>
std::string input_str = "this is a -string-, which is a sequence based on the -char- type.";
std::wstring input_wstr = L"this is a -wide- string, which is based on the -wchar_t- type.";
// conversion
std::wstring str_turned_to_wstr = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(input_str);
std::string wstr_turned_to_str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(input_wstr);
ユーザビリティや可読性を向上させるために、変換を実行する関数を定義することができます。
#include <string>
#include <codecvt>
#include <locale>
using convert_t = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_t, wchar_t> strconverter;
std::string to_string(std::wstring wstr)
{
return strconverter.to_bytes(wstr);
}
std::wstring to_wstring(std::string str)
{
return strconverter.from_bytes(str);
}
サンプル使用法:
std::wstring a_wide_string = to_wstring("Hello World!");
確かにstd::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("Hello World!")
よりも読みやすくなります。
char
とwchar_t
はエンコーディングを意味するものではなく、サイズをバイト単位で示していないことに注意してください。たとえば、 wchar_t
は2バイトのデータ型として一般的に実装されており、通常Windows(Windows 2000より前のバージョンではUCS-2)でUTF-16でエンコードされたデータを、UTF-32でエンコードされた4バイトのデータ型Linux。これは、C ++ 11で導入された新しいタイプのchar16_t
およびchar32_t
とは異なり、UTF16またはUTF32の "文字"(またはより正確にはコードポイント )を保持するのに十分な大きさであることが保証されています。
std :: string_viewクラスの使用
C ++ 17では、 std::string_view
導入されていstd::string_view
。これはconst char
の非所有範囲であり、ポインタのペアまたはポインタと長さのいずれかとして実装できます。これは変更不可能な文字列データを必要とする関数のための優れたパラメータ型です。 C ++ 17より前には、このために3つのオプションがありました。
void foo(std::string const& s); // pre-C++17, single argument, could incur
// allocation if caller's data was not in a string
// (e.g. string literal or vector<char> )
void foo(const char* s, size_t len); // pre-C++17, two arguments, have to pass them
// both everywhere
void foo(const char* s); // pre-C++17, single argument, but need to call
// strlen()
template <class StringT>
void foo(StringT const& s); // pre-C++17, caller can pass arbitrary char data
// provider, but now foo() has to live in a header
これらのすべてを次のものに置き換えることができます。
void foo(std::string_view s); // post-C++17, single argument, tighter coupling
// zero copies regardless of how caller is storing
// the data
std::string_view
はその基礎データを変更できないことに注意してください 。
string_view
は不要なコピーを避けたい場合に便利です。
これはstd::string
が行う機能の便利なサブセットを提供しますが、関数のいくつかは異なった動作をします:
std::string str = "lllloooonnnngggg sssstttrrriiinnnggg"; //A really long string
//Bad way - 'string::substr' returns a new string (expensive if the string is long)
std::cout << str.substr(15, 10) << '\n';
//Good way - No copies are created!
std::string_view view = str;
// string_view::substr returns a new string_view
std::cout << view.substr(15, 10) << '\n';
各文字をループする
std::string
はイテレータをサポートしているので、それぞれの文字を繰り返し処理するためには、 遠隔ベースのループを使うことができます:
std::string str = "Hello World!";
for (auto c : str)
std::cout << c;
「伝統的な」 for
ループを使用すると、すべての文字をループできます。
std::string str = "Hello World!";
for (std::size_t i = 0; i < str.length(); ++i)
std::cout << str[i];
整数/浮動小数点型への変換
数値を含むstd::string
は、変換関数を使用して整数型または浮動小数点型に変換できます。
これらの関数はすべて、数字以外の文字が出現するとすぐに入力文字列の解析を停止するので、 "123abc"
は123
に変換されます。
関数std::ato*
は、Cスタイルの文字列(文字配列)を整数型または浮動小数点型に変換します。
std::string ten = "10";
double num1 = std::atof(ten.c_str());
int num2 = std::atoi(ten.c_str());
long num3 = std::atol(ten.c_str());
long long num4 = std::atoll(ten.c_str());
ただし、これらの関数の使用は、文字列の解析に失敗した場合に0
を返すため、使用しないでください。たとえば、入力文字列が "0"の場合、 0
が有効な結果になる可能性があるため、変換が実際に失敗したかどうかを判断することはできないため、これは悪いことです。
より新しいstd::sto*
関数群は、 std::string
を整数型または浮動小数点型に変換し、入力を解析できなかった場合は例外をスローします。 可能であれば、これらの機能を使用する必要があります 。
std::string ten = "10";
int num1 = std::stoi(ten);
long num2 = std::stol(ten);
long long num3 = std::stoll(ten);
float num4 = std::stof(ten);
double num5 = std::stod(ten);
long double num6 = std::stold(ten);
さらに、これらの関数は、 std::ato*
ファミリとは異なり、8進数と16進数の文字列も処理します。 2番目のパラメータは、入力文字列の最初の変換されていない文字(ここでは図示していません)へのポインタで、3番目のパラメータは使用する基数です。 0
は8進数( 0
始まる)と16進数( 0x
または0X
始まる)の自動検出で、その他の値は使用する基数です
std::string ten = "10";
std::string ten_octal = "12";
std::string ten_hex = "0xA";
int num1 = std::stoi(ten, 0, 2); // Returns 2
int num2 = std::stoi(ten_octal, 0, 8); // Returns 10
long num3 = std::stol(ten_hex, 0, 16); // Returns 10
long num4 = std::stol(ten_hex); // Returns 0
long num5 = std::stol(ten_hex, 0, 0); // Returns 10 as it detects the leading 0x
文字エンコーディング間の変換
C ++ 11ではエンコーディング間の変換が容易で、ほとんどのコンパイラは<codecvt>
と<locale>
ヘッダを使用してクロスプラットフォームで処理でき<locale>
。
#include <iostream>
#include <codecvt>
#include <locale>
#include <string>
using namespace std;
int main() {
// converts between wstring and utf8 string
wstring_convert<codecvt_utf8_utf16<wchar_t>> wchar_to_utf8;
// converts between u16string and utf8 string
wstring_convert<codecvt_utf8_utf16<char16_t>, char16_t> utf16_to_utf8;
wstring wstr = L"foobar";
string utf8str = wchar_to_utf8.to_bytes(wstr);
wstring wstr2 = wchar_to_utf8.from_bytes(utf8str);
wcout << wstr << endl;
cout << utf8str << endl;
wcout << wstr2 << endl;
u16string u16str = u"foobar";
string utf8str2 = utf16_to_utf8.to_bytes(u16str);
u16string u16str2 = utf16_to_utf8.from_bytes(utf8str2);
return 0;
}
Visual Studioの2015年は、これらの変換のためのサポートを提供しますが、ことを覚えバグ彼らのライブラリの実装では、のために別のテンプレートを使用する必要がwstring_convert
を扱うときchar16_t
:
using utf16_char = unsigned short;
wstring_convert<codecvt_utf8_utf16<utf16_char>, utf16_char> conv_utf8_utf16;
void strings::utf16_to_utf8(const std::u16string& utf16, std::string& utf8)
{
std::basic_string<utf16_char> tmp;
tmp.resize(utf16.length());
std::copy(utf16.begin(), utf16.end(), tmp.begin());
utf8 = conv_utf8_utf16.to_bytes(tmp);
}
void strings::utf8_to_utf16(const std::string& utf8, std::u16string& utf16)
{
std::basic_string<utf16_char> tmp = conv_utf8_utf16.from_bytes(utf8);
utf16.clear();
utf16.resize(tmp.length());
std::copy(tmp.begin(), tmp.end(), utf16.begin());
}
文字列が別の文字列の接頭辞かどうかを確認する
C ++ 14では、これはstd::mismatch
によって簡単に実行され、最初の不一致のペアを2つの範囲から戻します。
std::string prefix = "foo";
std::string string = "foobar";
bool isPrefix = std::mismatch(prefix.begin(), prefix.end(),
string.begin(), string.end()).first == prefix.end();
mismatch()
範囲と半分のバージョンはC ++ 14より前に存在していましたが、2番目の文字列が2番目の文字列のほうが短い場合は安全ではありません。
私たちはまだstd::mismatch()
の範囲とバージョンを使うことができますが、最初に最初の文字列が2番目の文字列と同じ大きさであることを確認する必要があります:
bool isPrefix = prefix.size() <= string.size() &&
std::mismatch(prefix.begin(), prefix.end(),
string.begin(), string.end()).first == prefix.end();
std::string_view
では、割り当てのオーバーヘッドやコピーを心配することなく、直接比較を行うことができます。
bool isPrefix(std::string_view prefix, std::string_view full)
{
return prefix == full.substr(0, prefix.size());
}
std :: stringに変換する
std::ostringstream
オブジェクトを(ストリーム挿入演算子<<
) std::ostringstream
オブジェクトに挿入し、 std::ostringstream
全体をstd::ostringstream
に変換することによって、ストリーミング可能な型を文字列表現に変換することができますstd::string
。
int
の場合:
#include <sstream>
int main()
{
int val = 4;
std::ostringstream str;
str << val;
std::string converted = str.str();
return 0;
}
独自の変換関数を書くと、単純な:
template<class T>
std::string toString(const T& x)
{
std::ostringstream ss;
ss << x;
return ss.str();
}
パフォーマンスは重要なコードには適していません。
必要に応じて、ユーザー定義のクラスでストリーム挿入演算子を実装できます。
std::ostream operator<<( std::ostream& out, const A& a )
{
// write a string representation of a to out
return out;
}
ストリームとは別に、C ++ 11以降、すべての基本型に対してオーバーロードされたstd::to_string
(およびstd::to_wstring
)関数を使用して、そのパラメータの文字列表現を返すこともできます。
std::string s = to_string(0x12f3); // after this the string s contains "4851"