C++のstd::stringと文字列操作の標準ライブラリを完全ガイド

C++プログラミングにおいて、文字列操作は非常に重要なスキルです。C++の標準ライブラリには、文字列操作を効率的に行うための様々なツールが含まれています。その中でも、std::stringクラスは基本的な文字列操作をサポートし、多くの便利な機能を提供しています。本記事では、std::stringクラスの基本操作から応用テクニックまでを詳しく解説し、実践的なコード例と演習問題を通じて、読者がC++での文字列操作をマスターできるようサポートします。

目次

std::stringの基本操作

std::stringクラスはC++の標準ライブラリで提供される文字列クラスで、基本的な文字列操作を簡単に行うことができます。ここでは、std::stringの初期化や基本的な操作方法について解説します。

std::stringの初期化

std::stringオブジェクトを初期化する方法はいくつかあります。以下に例を示します。

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello, World!"; // 文字列リテラルから初期化
    std::string str2("Hello, C++!");    // コンストラクタを使用して初期化
    std::string str3(str1);             // コピーコンストラクタを使用して初期化
    std::string str4(5, 'A');           // 同じ文字を繰り返して初期化

    std::cout << str1 << std::endl;
    std::cout << str2 << std::endl;
    std::cout << str3 << std::endl;
    std::cout << str4 << std::endl;

    return 0;
}

std::stringの基本操作

次に、std::stringの基本的な操作方法を紹介します。

文字の追加と削除

std::stringに文字を追加したり削除したりする方法は以下の通りです。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello";

    str += ", World!"; // 文字列の追加
    std::cout << str << std::endl; // 出力: Hello, World!

    str.push_back('!'); // 文字の追加
    std::cout << str << std::endl; // 出力: Hello, World!!

    str.pop_back(); // 文字の削除
    std::cout << str << std::endl; // 出力: Hello, World!

    return 0;
}

文字列の長さとクリア

文字列の長さを取得したり、文字列をクリアする方法も簡単です。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";

    std::cout << "Length: " << str.length() << std::endl; // 文字列の長さを取得
    str.clear(); // 文字列をクリア
    std::cout << "Length after clear: " << str.length() << std::endl; // 出力: 0

    return 0;
}

文字列のアクセス

std::string内の特定の文字にアクセスする方法です。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";

    std::cout << "First character: " << str[0] << std::endl; // 出力: H
    std::cout << "Last character: " << str[str.length() - 1] << std::endl; // 出力: !

    str[0] = 'h'; // 文字の変更
    std::cout << "Modified string: " << str << std::endl; // 出力: hello, World!

    return 0;
}

以上が、std::stringの基本操作のいくつかです。次のセクションでは、文字列の連結と比較について詳しく見ていきます。

文字列の連結と比較

C++の標準ライブラリstd::stringでは、文字列の連結や比較を簡単に行うことができます。ここでは、これらの基本操作について詳しく解説します。

文字列の連結

文字列を連結するには、+演算子やappendメソッドを使用します。

`+`演算子を使用した連結

+演算子を使って簡単に文字列を連結することができます。

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello";
    std::string str2 = "World";

    std::string result = str1 + ", " + str2 + "!"; // 文字列の連結
    std::cout << result << std::endl; // 出力: Hello, World!

    return 0;
}

`append`メソッドを使用した連結

appendメソッドを使用して、文字列を連結することも可能です。

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello";
    std::string str2 = "World";

    str1.append(", ").append(str2).append("!"); // 文字列の連結
    std::cout << str1 << std::endl; // 出力: Hello, World!

    return 0;
}

文字列の比較

文字列を比較するためには、==演算子やcompareメソッドを使用します。

`==`演算子を使用した比較

==演算子を使って、二つの文字列が等しいかどうかを簡単に比較できます。

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello";
    std::string str2 = "World";
    std::string str3 = "Hello";

    if (str1 == str2) {
        std::cout << "str1 and str2 are equal." << std::endl;
    } else {
        std::cout << "str1 and str2 are not equal." << std::endl; // 出力: not equal
    }

    if (str1 == str3) {
        std::cout << "str1 and str3 are equal." << std::endl; // 出力: equal
    }

    return 0;
}

`compare`メソッドを使用した比較

compareメソッドを使用すると、文字列の辞書順比較が可能です。

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello";
    std::string str2 = "World";

    int result = str1.compare(str2);

    if (result == 0) {
        std::cout << "str1 and str2 are equal." << std::endl;
    } else if (result < 0) {
        std::cout << "str1 is less than str2." << std::endl; // 出力: less than
    } else {
        std::cout << "str1 is greater than str2." << std::endl;
    }

    return 0;
}

以上が、文字列の連結と比較の基本的な方法です。次のセクションでは、部分文字列の抽出方法について解説します。

部分文字列の抽出

C++の標準ライブラリstd::stringでは、部分文字列を簡単に抽出することができます。ここでは、その方法について詳しく解説します。

substrメソッドを使用した部分文字列の抽出

部分文字列を抽出するためには、substrメソッドを使用します。このメソッドは、開始位置と長さを指定して部分文字列を取得します。

基本的な使用例

以下は、substrメソッドを使った基本的な例です。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";

    std::string substr1 = str.substr(0, 5);  // "Hello"
    std::string substr2 = str.substr(7, 5);  // "World"

    std::cout << "Substring 1: " << substr1 << std::endl; // 出力: Hello
    std::cout << "Substring 2: " << substr2 << std::endl; // 出力: World

    return 0;
}

部分文字列の抽出範囲

substrメソッドの引数には、開始位置と長さを指定しますが、長さを省略すると、開始位置から末尾までの部分文字列が抽出されます。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";

    std::string substr = str.substr(7);  // "World!"

    std::cout << "Substring: " << substr << std::endl; // 出力: World!

    return 0;
}

部分文字列の利用例

部分文字列は、文字列操作のさまざまな場面で役立ちます。例えば、特定の区切り文字で分割された文字列から、必要な部分だけを抽出する場合などです。

特定の区切り文字で分割された文字列の処理

例えば、CSV形式の文字列から特定の列を抽出する場合の例を示します。

#include <iostream>
#include <string>

int main() {
    std::string csv = "John,Doe,30,New York";

    size_t pos = csv.find(","); // 最初のカンマの位置を見つける
    std::string firstName = csv.substr(0, pos); // 最初のカンマまでの部分文字列を抽出

    csv = csv.substr(pos + 1); // 残りの文字列を更新
    pos = csv.find(","); // 次のカンマの位置を見つける
    std::string lastName = csv.substr(0, pos); // 次のカンマまでの部分文字列を抽出

    std::cout << "First Name: " << firstName << std::endl; // 出力: John
    std::cout << "Last Name: " << lastName << std::endl; // 出力: Doe

    return 0;
}

以上が、部分文字列の抽出方法とその利用例です。次のセクションでは、文字列の検索方法について解説します。

文字列の検索

C++の標準ライブラリstd::stringでは、文字列内で特定の文字や文字列を検索する方法が提供されています。ここでは、その方法について詳しく解説します。

findメソッドを使用した文字列の検索

findメソッドを使うと、文字列内で特定の文字や部分文字列を検索できます。このメソッドは、検索対象が最初に現れる位置を返します。

基本的な使用例

以下は、findメソッドを使った基本的な例です。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";

    size_t pos = str.find("World"); // "World"の開始位置を検索

    if (pos != std::string::npos) {
        std::cout << "'World' found at position: " << pos << std::endl; // 出力: 7
    } else {
        std::cout << "'World' not found" << std::endl;
    }

    return 0;
}

特定の文字の検索

findメソッドは、部分文字列だけでなく、単一の文字を検索することもできます。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";

    size_t pos = str.find('o'); // 最初の'o'の位置を検索

    if (pos != std::string::npos) {
        std::cout << "'o' found at position: " << pos << std::endl; // 出力: 4
    } else {
        std::cout << "'o' not found" << std::endl;
    }

    return 0;
}

rfindメソッドを使用した逆方向の検索

rfindメソッドを使用すると、文字列の後ろから検索を行うことができます。これは、特定の文字や部分文字列が最後に現れる位置を検索するのに便利です。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World! Hello!";

    size_t pos = str.rfind("Hello"); // "Hello"が最後に現れる位置を検索

    if (pos != std::string::npos) {
        std::cout << "'Hello' found at last position: " << pos << std::endl; // 出力: 13
    } else {
        std::cout << "'Hello' not found" << std::endl;
    }

    return 0;
}

find_first_ofとfind_last_ofメソッド

find_first_ofメソッドとfind_last_ofメソッドを使用すると、指定した文字セットの中から最初または最後に現れる文字の位置を検索することができます。

find_first_ofメソッドの使用例

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    std::string charset = "aeiou"; // 母音セット

    size_t pos = str.find_first_of(charset); // 最初に現れる母音の位置を検索

    if (pos != std::string::npos) {
        std::cout << "First vowel found at position: " << pos << std::endl; // 出力: 1 (e)
    } else {
        std::cout << "No vowels found" << std::endl;
    }

    return 0;
}

find_last_ofメソッドの使用例

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    std::string charset = "aeiou"; // 母音セット

    size_t pos = str.find_last_of(charset); // 最後に現れる母音の位置を検索

    if (pos != std::string::npos) {
        std::cout << "Last vowel found at position: " << pos << std::endl; // 出力: 8 (o)
    } else {
        std::cout << "No vowels found" << std::endl;
    }

    return 0;
}

以上が、文字列の検索方法の基本です。次のセクションでは、文字列の置換方法について解説します。

文字列の置換

C++の標準ライブラリstd::stringでは、文字列の一部を別の文字列に置換することができます。ここでは、文字列の置換方法について詳しく解説します。

replaceメソッドを使用した文字列の置換

replaceメソッドを使用すると、文字列の一部を別の文字列に置換することができます。以下に基本的な使用例を示します。

基本的な使用例

以下は、replaceメソッドを使って文字列を置換する例です。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";

    // 位置5から6文字分を"Universe"に置換
    str.replace(7, 5, "Universe");
    std::cout << str << std::endl; // 出力: Hello, Universe!

    return 0;
}

部分文字列の置換

文字列内の特定の部分文字列を置換するために、まずfindメソッドで置換対象の位置を見つけ、その位置に対してreplaceメソッドを使用します。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    std::string from = "World";
    std::string to = "Universe";

    size_t start_pos = str.find(from);
    if (start_pos != std::string::npos) {
        str.replace(start_pos, from.length(), to);
    }
    std::cout << str << std::endl; // 出力: Hello, Universe!

    return 0;
}

複数の部分文字列を一度に置換

全ての部分文字列を置換するためには、ループを使用して文字列全体を走査し、繰り返し置換を行います。

#include <iostream>
#include <string>

void replaceAll(std::string& str, const std::string& from, const std::string& to) {
    if (from.empty())
        return;
    size_t start_pos = 0;
    while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length(); // 次の位置を更新
    }
}

int main() {
    std::string str = "Hello, World! World is beautiful.";
    replaceAll(str, "World", "Universe");
    std::cout << str << std::endl; // 出力: Hello, Universe! Universe is beautiful.

    return 0;
}

部分的な文字列の置換

文字列内の特定の位置から特定の長さ分の文字列を別の文字列に置換することも可能です。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";

    // 位置0から5文字分を"Hi"に置換
    str.replace(0, 5, "Hi");
    std::cout << str << std::endl; // 出力: Hi, World!

    return 0;
}

以上が、文字列の置換方法の基本です。次のセクションでは、文字列の変換方法について解説します。

文字列の変換

C++の標準ライブラリstd::stringでは、整数や浮動小数点数などを文字列に変換する方法が提供されています。ここでは、その方法について詳しく解説します。

数値から文字列への変換

C++11以降では、数値から文字列への変換にはstd::to_string関数を使用します。

基本的な使用例

以下は、std::to_string関数を使って整数や浮動小数点数を文字列に変換する例です。

#include <iostream>
#include <string>

int main() {
    int num = 42;
    double pi = 3.14159;

    std::string str_num = std::to_string(num);
    std::string str_pi = std::to_string(pi);

    std::cout << "Integer to string: " << str_num << std::endl; // 出力: 42
    std::cout << "Double to string: " << str_pi << std::endl;  // 出力: 3.141590

    return 0;
}

文字列から数値への変換

文字列を数値に変換するには、std::stoistd::stolstd::stollstd::stofstd::stodstd::stoldなどの関数を使用します。

基本的な使用例

以下は、文字列を整数や浮動小数点数に変換する例です。

#include <iostream>
#include <string>

int main() {
    std::string str_num = "42";
    std::string str_pi = "3.14159";

    int num = std::stoi(str_num);
    double pi = std::stod(str_pi);

    std::cout << "String to integer: " << num << std::endl; // 出力: 42
    std::cout << "String to double: " << pi << std::endl;  // 出力: 3.14159

    return 0;
}

数値の書式設定

数値を文字列に変換する際に、特定の書式設定を行いたい場合は、std::stringstreamを使用します。

基本的な使用例

以下は、std::stringstreamを使って数値を特定の書式で文字列に変換する例です。

#include <iostream>
#include <iomanip> // std::setprecision を使用するため
#include <sstream>
#include <string>

int main() {
    double pi = 3.14159;
    std::stringstream ss;

    ss << std::fixed << std::setprecision(2) << pi;
    std::string str_pi = ss.str();

    std::cout << "Formatted double to string: " << str_pi << std::endl; // 出力: 3.14

    return 0;
}

文字列の大文字・小文字変換

文字列全体を大文字や小文字に変換する方法も紹介します。

大文字への変換

#include <iostream>
#include <string>
#include <algorithm>

int main() {
    std::string str = "Hello, World!";

    std::transform(str.begin(), str.end(), str.begin(), ::toupper);
    std::cout << "Uppercase string: " << str << std::endl; // 出力: HELLO, WORLD!

    return 0;
}

小文字への変換

#include <iostream>
#include <string>
#include <algorithm>

int main() {
    std::string str = "Hello, World!";

    std::transform(str.begin(), str.end(), str.begin(), ::tolower);
    std::cout << "Lowercase string: " << str << std::endl; // 出力: hello, world!

    return 0;
}

以上が、文字列の変換方法の基本です。次のセクションでは、文字列の分割方法について解説します。

文字列の分割

C++の標準ライブラリstd::stringでは、特定の区切り文字で文字列を分割する方法があります。ここでは、その方法について詳しく解説します。

std::getlineを使用した文字列の分割

std::getline関数を使用して、文字列を特定の区切り文字で分割することができます。通常、行単位で読み込むために使用されますが、区切り文字を指定することも可能です。

基本的な使用例

以下は、std::getlineを使って文字列をカンマで分割する例です。

#include <iostream>
#include <string>
#include <sstream>
#include <vector>

int main() {
    std::string str = "apple,banana,cherry";
    std::vector<std::string> result;
    std::istringstream ss(str);
    std::string item;

    while (std::getline(ss, item, ',')) {
        result.push_back(item);
    }

    for (const auto& s : result) {
        std::cout << s << std::endl; // 出力: apple, banana, cherry
    }

    return 0;
}

std::stringのfindとsubstrを使用した文字列の分割

findメソッドとsubstrメソッドを組み合わせることで、文字列を手動で分割することもできます。

基本的な使用例

以下は、findsubstrを使って文字列をカンマで分割する例です。

#include <iostream>
#include <string>
#include <vector>

int main() {
    std::string str = "apple,banana,cherry";
    std::vector<std::string> result;
    size_t start = 0;
    size_t end = str.find(',');

    while (end != std::string::npos) {
        result.push_back(str.substr(start, end - start));
        start = end + 1;
        end = str.find(',', start);
    }
    result.push_back(str.substr(start));

    for (const auto& s : result) {
        std::cout << s << std::endl; // 出力: apple, banana, cherry
    }

    return 0;
}

Boostライブラリを使用した文字列の分割

Boostライブラリのboost::algorithm::split関数を使用すると、より簡単に文字列を分割することができます。Boostライブラリを使用するには、事前にインストールが必要です。

基本的な使用例

以下は、Boostライブラリを使って文字列をカンマで分割する例です。

#include <iostream>
#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>

int main() {
    std::string str = "apple,banana,cherry";
    std::vector<std::string> result;

    boost::split(result, str, boost::is_any_of(","));

    for (const auto& s : result) {
        std::cout << s << std::endl; // 出力: apple, banana, cherry
    }

    return 0;
}

std::regexを使用した文字列の分割

C++11以降では、正規表現を使用して文字列を分割することも可能です。

基本的な使用例

以下は、std::regexを使って文字列をカンマで分割する例です。

#include <iostream>
#include <string>
#include <vector>
#include <regex>

int main() {
    std::string str = "apple,banana,cherry";
    std::regex re(",");
    std::sregex_token_iterator first{str.begin(), str.end(), re, -1}, last;
    std::vector<std::string> result{first, last};

    for (const auto& s : result) {
        std::cout << s << std::endl; // 出力: apple, banana, cherry
    }

    return 0;
}

以上が、文字列の分割方法の基本です。次のセクションでは、正規表現を用いた高度な文字列操作について解説します。

高度な文字列操作

C++の標準ライブラリには、正規表現を用いた高度な文字列操作をサポートする機能があります。正規表現を使うことで、複雑な文字列操作を簡単に実行できます。ここでは、正規表現を用いた文字列操作について解説します。

正規表現を用いた検索

正規表現を使って文字列内のパターンを検索することができます。C++11以降では、std::regex_searchを使用します。

基本的な使用例

以下は、std::regex_searchを使って文字列内のパターンを検索する例です。

#include <iostream>
#include <string>
#include <regex>

int main() {
    std::string str = "The quick brown fox jumps over the lazy dog";
    std::regex re("\\b\\w{4}\\b");
    std::smatch match;

    while (std::regex_search(str, match, re)) {
        std::cout << "Found: " << match.str() << std::endl;
        str = match.suffix().str(); // 残りの文字列を更新
    }

    return 0;
}

正規表現を用いた置換

正規表現を使って文字列内の特定のパターンを置換するには、std::regex_replaceを使用します。

基本的な使用例

以下は、std::regex_replaceを使って文字列内のパターンを置換する例です。

#include <iostream>
#include <string>
#include <regex>

int main() {
    std::string str = "The quick brown fox jumps over the lazy dog";
    std::regex re("quick\\s(brown\\sfox)");
    std::string replacement = "swift $1";

    std::string result = std::regex_replace(str, re, replacement);
    std::cout << result << std::endl; // 出力: The swift brown fox jumps over the lazy dog

    return 0;
}

正規表現を用いた分割

std::regex_token_iteratorを使って正規表現を用いた文字列の分割を行うことができます。

基本的な使用例

以下は、std::regex_token_iteratorを使って文字列を分割する例です。

#include <iostream>
#include <string>
#include <vector>
#include <regex>

int main() {
    std::string str = "one,two,three,four";
    std::regex re(",");
    std::sregex_token_iterator first{str.begin(), str.end(), re, -1}, last;
    std::vector<std::string> tokens{first, last};

    for (const auto& token : tokens) {
        std::cout << token << std::endl; // 出力: one, two, three, four
    }

    return 0;
}

正規表現のパターンマッチング

正規表現を使用して文字列内で複雑なパターンをマッチングさせることも可能です。これにより、特定の形式に一致する文字列を抽出できます。

基本的な使用例

以下は、メールアドレスの形式に一致する文字列を抽出する例です。

#include <iostream>
#include <string>
#include <regex>

int main() {
    std::string str = "Contact us at info@example.com or support@example.org";
    std::regex re(R"(([\w\.-]+)@([\w\.-]+)\.([\w\.]{2,}))");
    std::smatch match;

    while (std::regex_search(str, match, re)) {
        std::cout << "Found email: " << match.str() << std::endl;
        str = match.suffix().str(); // 残りの文字列を更新
    }

    return 0;
}

以上が、正規表現を用いた高度な文字列操作の基本です。次のセクションでは、std::stringとパフォーマンスについて解説します。

std::stringとパフォーマンス

C++のstd::stringは強力で便利な文字列操作機能を提供しますが、パフォーマンス面での考慮も重要です。ここでは、std::stringのパフォーマンスに関する考察と最適化のポイントについて解説します。

メモリ管理とstd::string

std::stringは動的にメモリを管理するため、メモリ割り当てと解放が頻繁に行われる場合、パフォーマンスに影響を与えることがあります。

リザーブによるメモリ確保

多くの文字列操作を行う場合、reserveメソッドを使用して事前にメモリを確保することで、メモリ再割り当ての回数を減らし、パフォーマンスを向上させることができます。

#include <iostream>
#include <string>

int main() {
    std::string str;
    str.reserve(100); // 事前に100文字分のメモリを確保

    str = "This is a test string.";
    std::cout << str << std::endl;

    return 0;
}

文字列の連結とパフォーマンス

頻繁な文字列連結は、メモリの再割り当てが発生し、パフォーマンスが低下する可能性があります。これを避けるために、std::stringstreamを使用すると効果的です。

std::stringstreamを使用した連結

std::stringstreamを使用すると、連結操作が効率的になります。

#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::stringstream ss;
    ss << "Hello, ";
    ss << "World!";

    std::string result = ss.str();
    std::cout << result << std::endl; // 出力: Hello, World!

    return 0;
}

コピー操作の最小化

std::stringオブジェクトのコピーは、特に大きな文字列の場合、コストが高くなります。これを避けるために、ムーブセマンティクスを活用できます。

ムーブセマンティクスの利用

C++11以降では、ムーブセマンティクスを利用して、オブジェクトの所有権を効率的に転送できます。

#include <iostream>
#include <string>

void processString(std::string str) {
    std::cout << "Processing: " << str << std::endl;
}

int main() {
    std::string str = "Hello, World!";
    processString(std::move(str)); // ムーブセマンティクスを使用して所有権を転送

    std::cout << "After move, str is: " << str << std::endl; // 出力: 空文字列

    return 0;
}

小さな文字列の最適化(SBO)

多くの実装では、std::stringは「小さな文字列の最適化(Small String Optimization, SBO)」を使用しています。これは、短い文字列を内部バッファに格納し、動的メモリ割り当てを避ける最適化です。

SBOのメリット

SBOにより、短い文字列の操作がより高速になります。以下の例では、短い文字列の連結が高速に行われることを示しています。

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello";
    std::string str2 = "World";
    std::string result = str1 + ", " + str2 + "!";

    std::cout << result << std::endl; // 出力: Hello, World!

    return 0;
}

SBOにより、短い文字列の連結が高速に行われるため、頻繁に連結操作を行う場合にパフォーマンスが向上します。

以上が、std::stringとパフォーマンスに関する基本的な考慮点です。次のセクションでは、実践例と演習問題を通じて理解を深めます。

実践例と演習問題

ここでは、これまでに学んだC++のstd::stringの機能を実践例を通じて確認し、理解を深めるための演習問題を提供します。

実践例

次の例では、ユーザーから入力されたCSV形式のデータをパースして処理するプログラムを示します。このプログラムは、std::stringの分割、置換、変換などの機能を使用しています。

CSVパーサープログラム

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>

// CSV行をパースしてベクターに変換する関数
std::vector<std::string> parseCSVLine(const std::string& line) {
    std::vector<std::string> result;
    std::istringstream ss(line);
    std::string item;

    while (std::getline(ss, item, ',')) {
        result.push_back(item);
    }

    return result;
}

// メイン関数
int main() {
    std::string csvData = "John,Doe,30,New York\nJane,Smith,25,Los Angeles";
    std::istringstream ss(csvData);
    std::string line;

    // 各行をパースして表示
    while (std::getline(ss, line)) {
        std::vector<std::string> parsedLine = parseCSVLine(line);

        for (const auto& item : parsedLine) {
            std::cout << item << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

このプログラムは、CSV形式の文字列をパースし、各フィールドを個別に表示します。

演習問題

以下の演習問題に取り組むことで、std::stringの機能についての理解を深めてください。

演習問題1: 文字列の逆転

ユーザーから入力された文字列を逆転して表示するプログラムを作成してください。

解答例

#include <iostream>
#include <string>
#include <algorithm>

int main() {
    std::string str;
    std::cout << "Enter a string: ";
    std::getline(std::cin, str);

    std::reverse(str.begin(), str.end());
    std::cout << "Reversed string: " << str << std::endl;

    return 0;
}

演習問題2: 文字列内の単語数を数える

ユーザーから入力された文字列内の単語数を数えるプログラムを作成してください。単語はスペースで区切られているものとします。

解答例

#include <iostream>
#include <string>
#include <sstream>

int main() {
    std::string str;
    std::cout << "Enter a string: ";
    std::getline(std::cin, str);

    std::istringstream ss(str);
    std::string word;
    int wordCount = 0;

    while (ss >> word) {
        ++wordCount;
    }

    std::cout << "Number of words: " << wordCount << std::endl;

    return 0;
}

演習問題3: 文字列の置換

ユーザーから入力された文字列内の特定の単語を別の単語に置換するプログラムを作成してください。

解答例

#include <iostream>
#include <string>

void replaceAll(std::string& str, const std::string& from, const std::string& to) {
    if (from.empty()) return;
    size_t start_pos = 0;
    while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length();
    }
}

int main() {
    std::string str, from, to;
    std::cout << "Enter a string: ";
    std::getline(std::cin, str);
    std::cout << "Enter the word to replace: ";
    std::getline(std::cin, from);
    std::cout << "Enter the replacement word: ";
    std::getline(std::cin, to);

    replaceAll(str, from, to);
    std::cout << "Modified string: " << str << std::endl;

    return 0;
}

以上の演習問題に取り組むことで、std::stringの基本的な操作から応用までを実践的に理解できます。次のセクションでは、この記事のまとめを行います。

まとめ

C++の標準ライブラリで提供されるstd::stringは、非常に強力な文字列操作機能を持っています。本記事では、基本操作から始まり、文字列の連結、比較、部分文字列の抽出、検索、置換、変換、分割、そして正規表現を用いた高度な文字列操作までを詳しく解説しました。

std::stringは、C++プログラミングにおいて頻繁に使用されるデータ型であり、これを効率的に扱うための知識は、プログラムのパフォーマンスや可読性に大きな影響を与えます。また、実践例や演習問題を通じて、実際に手を動かして試すことで、理解を深めることができたと思います。

これらの知識を活用して、より効率的で読みやすいコードを書けるように練習してみてください。今後のプログラミングの参考になることを願っています。

コメント

コメントする

目次