サーチ…


前書き

文字列は、文字列を表すオブジェクトです。標準の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のメソッドatindex >= size()場合にstd::out_of_range例外atスローします。

operator[]の動作は少し複雑です。すべての場合、 index > size()場合は未定義の動作をしindex > size()が、 index == size()場合は動作しません。

C ++ 11
  1. 非const文字列では、動作は未定義です。
  2. const文字列では、値がCharT()ヌル文字)の文字への参照が返されます。
C ++ 11
  1. CharT()ヌル文字)を持つ文字への参照が返されます。
  2. この参照を変更することは未定義の動作です。

代わりに使用する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!"
C ++ 14
//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!"
C ++ 11
//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 strreplace 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'
C ++ 11

注意:文字列が空の場合、これらの例のどちらも未定義の動作になります。


前面()

最初の文字への参照を返します。

char c = str.front(); // 'H'

バック()

最後の文字への参照を返します。

char c = str.back(); // '!'

トークン化

実行時に最も安いものから最も高価なものまでリストされています:

  1. 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);

実例

  1. 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>());

実例

  1. std::regex_token_iteratorstd::regexを使って反復的にトークン化します。これは、より柔軟な区切り文字の定義を提供します。たとえば、区切り文字で区切られていないカンマや空白文字は次のようになります。
C ++ 11
// 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メソッドだけが呼び出される可能性があります。

C ++ 17

data()メンバー関数を使用して、 std::stringオブジェクトのデータを操作するために使用できる変更可能なchar*を取得できます。

C ++ 11

変更可能なchar*は、最初の文字: &s[0]アドレスを取得することによっても取得できます。 C ++ 11では、整形式のヌル終了文字列が生成されることが保証されています。なお、 &s[0]としてもよく、形成されるs空である、一方&s.front()未定義であるs空です。

C ++ 11
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>というヘッダが必要です。

C ++ 11

シーケンスまたは文字列をトリミングするとは、特定の述語に一致するすべての先頭および末尾の要素(または文字)を削除することを意味します。最初の要素は、要素を移動することを伴わないため、最初の要素をトリムし、先頭の要素をトリムします。以下の一般化はstd::basic_string (例えばstd::stringstd::wstring )のすべての型で動作し、また誤ってシーケンスコンテナ( std::vectorstd::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の場合、すなわち、 inまたはm以上でm場合、それは最も低い値とみなされる。


次に、 < :を使用する例を示します。

std::string str1 = "Barr";
std::string str2 = "Bar";

assert(str2 < str1);

手順は次のとおりです。

  1. 最初の文字を比較すると、 'B' == 'B' - 移動します。
  2. 2番目の文字'a' == 'a'比較する - 移動する。
  3. 3番目の文字'r' == 'r'比較する - 移動する。
  4. str1範囲はまだ文字を持っていますが、 str2範囲は使い尽くされています。したがって、 str2 < str1

std :: wstringへの変換

C ++では、文字のシーケンスは、 std::basic_stringクラスをネイティブ文字タイプで特殊化することによって表現されます。標準ライブラリで定義されている2つの主要コレクションは、 std::stringstd::wstringです。

  • std::stringchar型の要素で構築されています

  • std::wstringwchar_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!")よりも読みやすくなります。


charwchar_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

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';

各文字をループする

C ++ 11

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());
C ++ 11
long long num4 = std::atoll(ten.c_str());

ただし、これらの関数の使用は、文字列の解析に失敗した場合に0を返すため、使用しないでください。たとえば、入力文字列が "0"の場合、 0が有効な結果になる可能性があるため、変換が実際に失敗したかどうかを判断することはできないため、これは悪いことです。

より新しいstd::sto*関数群は、 std::stringを整数型または浮動小数点型に変換し、入力を解析できなかった場合は例外をスローします。 可能であれば、これらの機能を使用する必要があります

C ++ 11
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

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番目の文字列のほうが短い場合は安全ではありません。

C ++ 14

私たちはまだstd::mismatch()の範囲とバージョンを使うことができますが、最初に最初の文字列が2番目の文字列と同じ大きさであることを確認する必要があります:

bool isPrefix = prefix.size() <= string.size() &&
    std::mismatch(prefix.begin(), prefix.end(),
        string.begin(), string.end()).first == prefix.end();
C ++ 17

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

ストリームとは別に、C ++ 11以降、すべての基本型に対してオーバーロードされたstd::to_string (およびstd::to_wstring )関数を使用して、そのパラメータの文字列表現を返すこともできます。

std::string s = to_string(0x12f3);  // after this the string s contains "4851"


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow