C++: 文字列操作

最終更新:2026-08-31

レッスン19では string の基本を学びました。

でも、実際の開発では検索置換変換など、もっと高度な操作が必要です。

このレッスンでは、string の高度な操作を学びます。


1. 文字列の変更

(1) 1.1 文字列の削除(erase)

構文:

▶ サンプル 2:コード例(難易度 ⭐)

TEXT 📖 参照専用
string.erase(位置, 文字数);

例:

CPP
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello, World!";
    
    // 位置5から7文字削除(", World")
    text.erase(5, 7);
    
    std::cout << text << std::endl; // Hello!
    
    return 0;
}
💡 ヒント: 位置を指定しない場合、erase(pos)pos から最後まで削除します。


(2) 1.2 文字列の挿入(insert)

構文:

TEXT 📖 参照専用
string.insert(位置, 文字列);

例:

CPP
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello!";
    
    // 位置5に" World"を挿入
    text.insert(5, " World");
    
    std::cout << text << std::endl; // Hello World!
    
    return 0;
}

(3) 1.3 文字列のクリア(clear)

CPP
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello";
    text.clear(); // 文字列を空にする
    
    std::cout << "長さ:" << text.length() << std::endl; // 0
    std::cout << "空かどうか:" << text.empty() << std::endl; // 1(true)
    
    return 0;
}
💡 ヒント: empty() 関数は文字列が空かどうかを判定します(空なら true、つまり 1 を返す)。



2. 文字列の比較

==!=<> などの演算子を使うのが一般的ですが、compare() 関数も使えます。

(1) 2.1 基本的な使い方

CPP
#include <iostream>
#include <string>

int main() {
    std::string s1 = "apple";
    std::string s2 = "banana";
    
    int result = s1.compare(s2);
    
    if (result == 0) {
        std::cout << "s1 と s2 は等しい" << std::endl;
    } else if (result < 0) {
        std::cout << "s1 は s2 より小さい" << std::endl; // これが出力される
    } else {
        std::cout << "s1 は s2 より大きい" << std::endl;
    }
    
    return 0;
}

戻り値の意味:

💡 ヒント: 通常は ==!=<> などの演算子を使うほうが読みやすいです。



3. 文字列と数値の変換

(1) 3.1 数値から文字列へ(to_string)

CPP
#include <iostream>
#include <string>

int main() {
    int age = 25;
    double price = 19.99;
    
    std::string ageStr = std::to_string(age);
    std::string priceStr = std::to_string(price);
    
    std::cout << "年齢:" << ageStr << std::endl;
    std::cout << "価格:" << priceStr << std::endl;
    
    return 0;
}

出力:

TEXT 📖 参照専用
年齢:25
価格:19.990000
💡 ヒント: to_string() は小数点以下6桁まで表示します。精度を制御するには std::ostringstream または std::format(C++20)を使用してください。


(2) 3.2 文字列から数値へ(stoi、stod)

関数 用途
std::stoi(str) string → int int x = std::stoi("123");
std::stol(str) string → long long x = std::stol("123");
std::stoll(str) string → long long long long x = std::stoll("123");
std::stof(str) string → float float x = std::stof("3.14");
std::stod(str) string → double double x = std::stod("3.14");

例:

CPP
#include <iostream>
#include <string>

int main() {
    std::string numStr = "123";
    std::string priceStr = "19.99";
    
    int num = std::stoi(numStr);
    double price = std::stod(priceStr);
    
    std::cout << "num = " << num << std::endl;
    std::cout << "price = " << price << std::endl;
    
    return 0;
}

⚠️ 注意: 文字列が数値に変換できない場合、stoi / stod は例外を投げます。try-catch で処理してください。



4. 文字列の反復処理

(1) 4.1 インデックスを使用

CPP
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello";
    
    for (size_t i = 0; i < text.length(); i++) {
        std::cout << text[i] << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

(2) 4.2 範囲for文を使用(C++11以降)

CPP
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello";
    
    for (char c : text) {
        std::cout << c << " ";
    }
    std::cout << std::endl;
    
    return 0;
}
💡 ヒント: 範囲 for 文はより簡潔で、ループ条件を書く必要がありません。



5. 実践例:検索と置換

▶ サンプル 1:全件検索・置換(難易度 ⭐⭐)

CPP
#include <iostream>
#include <string>

int main() {
    std::string text = "I like C. C is powerful.";
    std::string oldStr = "C";
    std::string newStr = "C++";
    
    size_t pos = 0;
    while ((pos = text.find(oldStr, pos)) != std::string::npos) {
        text.replace(pos, oldStr.length(), newStr);
        pos += newStr.length(); // 置換後の位置へ移動
    }
    
    std::cout << "結果:" << text << std::endl;
    
    return 0;
}
▶ 試してみよう

出力:

TEXT 📖 参照専用
結果:I like C++. C++ is powerful.
💡 ヒント: 全件置換では、ループで検索位置を更新しながら処理します。


▶ サンプル 3:CSV行の解析(難易度 ⭐⭐)

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

std::vector<std::string> parseCSV(const std::string& line) {
    std::vector<std::string> fields;
    size_t start = 0;
    size_t end = line.find(',');

    while (end != std::string::npos) {
        fields.push_back(line.substr(start, end - start));
        start = end + 1;
        end = line.find(',', start);
    }
    fields.push_back(line.substr(start));  // 最後のフィールド

    return fields;
}

int main() {
    std::string csvLine = "Alice,25,92.5,A+";
    std::vector<std::string> fields = parseCSV(csvLine);

    std::cout << "解析結果:" << std::endl;
    for (size_t i = 0; i < fields.size(); i++) {
        std::cout << i + 1 << ": " << fields[i] << std::endl;
    }

    return 0;
}
▶ 試してみよう

出力:

TEXT 📖 参照専用
解析結果:
1: Alice
2: 25
3: 92.5
4: A+


❓ よくある質問

Q 文字列の長さに size_t を使う理由は? int ではだめ?
A string::length()size_t(符号なし)を返します。int を使うと警告が出る可能性があります。

推奨:

CPP
#include <iostream>
#include <string>

int main() {
    try {
        int x = std::stoi("abc"); // ❌ 変換不可、例外発生
    } catch (const std::invalid_argument& e) {
        std::cout << "エラー:" << e.what() << std::endl;
    }
    return 0;
}
Q 日本語文字列で length() を使うと?
A length() はバイト数を返します。UTF-8では日本語1文字が3バイトです。

ソースファイルがUTF-8の場合:

CPP
std::string s = "あいう";
std::cout << s.length() << std::endl; // 9(3文字×3バイト)

解決策:


📖 まとめ

  • erase()insert()clear() で文字列を変更
  • compare() で文字列を比較(通常は ==!= などの演算子で十分)
  • to_string() で数値から文字列へ
  • stoi() / stod() で文字列から数値へ
  • 文字列の反復には範囲for文を使用(C++11以降)

📝 練習問題

  1. 初級(難易度 ⭐): ユーザー入力の文字列から空白を削除するプログラムを書いてください。
    TEXT 📖 参照専用

入力:Hello World, this is C++! 出力:HelloWorld,thisisC++!


2. **中級(難易度 ⭐⭐):** 
ユーザー入力の文字列が「回文」かどうかを判定するプログラムを書いてください(前後逆にしても同じ、例:"level"、"radar")。
- ヒント:ポインタを使う方法、または反転して比較する方法があります。

3. **上級(難易度 ⭐⭐⭐):** 
簡易「シーザー暗号」を実装してください:
- 暗号化:各文字のASCIIコードを3ずらす(例:`'A'` → `'D'`)
- 復号:各文字のASCIIコードを3戻す
- ユーザー入力の文字列を暗号化・復号して出力

---

---
## 7. 🚀 次のステップ

文字列の高度な操作を理解したら、次は **フェーズ4(ポインタと参照)** へ —— C++の「核」であり、メモリを直接操作する強力な機能を学ぼう!
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%