C++: C++ 文字列(std::string)

最終更新:2026-08-31

C言語の文字列(char配列)を使うと、バグ(バッファオーバーフロー、\0忘れ)が起きやすいです。

C++の string クラス は、文字列をオブジェクトとしてカプセル化し、より安全で使いやすいインターフェースを提供します。


1. string とは?

(1) 1.1 string クラスの特徴

特徴 説明
安全性 string オブジェクトは自動的にメモリを管理
便利さ string は動的にサイズを変更、メモリ管理が不要
機能豊富 string のメンバー関数は多様な操作をサポート

string の利点:

  1. メモリ管理が不要 —— 自動的に拡張・縮小
  2. \0 を気にしなくていい —— 内部で処理
  3. 豊富な関数 —— 連結、検索、部分文字列など

(2) 1.2 string を使う理由?

C言語の文字列を使う場合:

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

CPP
#include <iostream>
#include <cstring>

int main() {
    char greeting[50] = "Hello, ";
    char name[] = "MOTO";
    
    std::strcat(greeting, name); // 連結
    std::cout << greeting << std::endl;
    
    return 0;
}
▶ 試してみよう

string を使う場合:

CPP
#include <iostream>
#include <string>

int main() {
    std::string greeting = "Hello, ";
    std::string name = "MOTO";
    
    greeting += name; // シンプルに連結
    std::cout << greeting << std::endl;
    
    return 0;
}


2. string の宣言と初期化

(1) 2.1 基本的な使い方

CPP
#include <iostream>
#include <string>

int main() {
    // 直接初期化
    std::string s1 = "Hello";
    
    // コンストラクタ使用
    std::string s2("World");
    
    // 文字繰り返し
    std::string s3(5, '*'); // "*****"
    
    std::cout << s1 << " " << s2 << " " << s3 << std::endl;
    
    return 0;
}

出力:

TEXT 📖 参照専用
Hello World *****
💡 ヒント: string を使うには #include <string> が必要です。



3. string の基本操作

(1) 3.1 文字列の連結(+ と +=)

CPP
#include <iostream>
#include <string>

int main() {
    std::string firstName = "MOTO";
    std::string lastName = "Zhang";
    
    // 方法1:+ 演算子
    std::string fullName1 = firstName + " " + lastName;
    std::cout << fullName1 << std::endl; // MOTO Zhang
    
    // 方法2:+= 演算子
    std::string fullName2 = firstName;
    fullName2 += " ";
    fullName2 += lastName;
    std::cout << fullName2 << std::endl; // MOTO Zhang
    
    return 0;
}

(2) 3.2 長さの取得(length と size)

CPP
#include <iostream>
#include <string>

int main() {
    std::string name = "MOTO";
    
    std::cout << "名前: " << name << std::endl;
    std::cout << "length(): " << name.length() << std::endl; // 4
    std::cout << "size(): " << name.size() << std::endl; // 4
    
    return 0;
}
💡 ヒント: length()size() は同じ機能です。お好みでどうぞ。

(3) 3.3 要素へのアクセス([] と at)

CPP
#include <iostream>
#include <string>

int main() {
    std::string name = "MOTO";
    
    // 方法1:[] 演算子
    std::cout << name[0] << std::endl; // M
    name[0] = 'm'; // 変更可能
    
    // 方法2:at() 関数(範囲チェックあり)
    std::cout << name.at(1) << std::endl; // o
    // name.at(10); // ❌ 例外を投げる(安全)
    
    return 0;
}
💡 ヒント:

  • name[i]高速、範囲チェックなし
  • name.at(i)安全、範囲外で例外を投げる


4. string のメンバー関数

(1) 4.1 文字列検索(find)

CPP
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello, World!";
    
    // 部分文字列を検索
    size_t pos = text.find("World");
    if (pos != std::string::npos) {
        std::cout << "\"World\"が見つかりました。位置: " << pos << std::endl; // 7
    } else {
        std::cout << "見つかりませんでした。" << std::endl;
    }
    
    return 0;
}
💡 ヒント: 見つからない場合、find()std::string::npos-1 のような値)を返します。

(2) 4.2 部分文字列(substr)

CPP
#include <iostream>
#include <string>

int main() {
    std::string email = "moto@example.com";
    
    // 位置0から4文字抽出
    std::string user = email.substr(0, 4);
    std::cout << "ユーザー名: " << user << std::endl; // moto
    
    // 位置5から最後まで抽出
    std::string domain = email.substr(5);
    std::cout << "ドメイン: " << domain << std::endl; // example.com
    
    return 0;
}

(3) 4.3 文字列置換(replace)

CPP
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello, World!";
    
    // 位置7から5文字を"C++"に置換
    text.replace(7, 5, "C++");
    std::cout << text << std::endl; // Hello, C++!
    
    return 0;
}


5. 文字列入力と出力

(1) 5.1 cin を使う(単語単位)

CPP
#include <iostream>
#include <string>

int main() {
    std::string name;
    
    std::cout << "名前を入力:";
    std::cin >> name; // ⚠️ スペースで区切られる
    
    std::cout << "こんにちは、" << name << "!" << std::endl;
    
    return 0;
}

出力例:

TEXT 📖 参照専用
名前を入力:MOTO Zhang
こんにちは、MOTO! ← "MOTO"だけが取得される

(2) 5.2 getline を使う(行単位)

CPP
#include <iostream>
#include <string>

int main() {
    std::string fullName;
    
    std::cout << "氏名を入力:";
    std::getline(std::cin, fullName); // ✅ スペース含めて取得
    
    std::cout << "こんにちは、" << fullName << "!" << std::endl;
    
    return 0;
}

出力例:

TEXT 📖 参照専用
氏名を入力:MOTO Zhang
こんにちは、MOTO Zhang! ← 全体が取得される
💡 ヒント: cin >>getline を併用する場合、cin.ignore() でバッファをクリアしてください!



6. 実践例:単語数カウント

▶ サンプル 1:単語数を数える(難易度 ⭐⭐)

CPP
#include <iostream>
#include <string>
#include <sstream> // stringstream用

int main() {
    std::string line;
    std::cout << "文章を入力:";
    std::getline(std::cin, line);
    
    // stringstreamで単語を分割
    std::istringstream ss(line);
    std::string word;
    int count = 0;
    
    while (ss >> word) {
        count++;
    }
    
    std::cout << "単語数:" << count << std::endl;
    
    return 0;
}
▶ 試してみよう

出力例:

TEXT 📖 参照専用
文章を入力:Hello World, this is C++!
単語数:5


7. よくあるエラー

(1) 7.1 #include <string> を忘れる

エラー例:

CPP
#include <iostream> // ❌ stringを含んでいない

int main() {
    std::string name = "MOTO"; // ❌ コンパイルエラー
    return 0;
}

解決: #include <string> を追加してください。

(2) 7.2 cin >> で文字列を取得する際の問題

エラー例:

CPP
#include <iostream>
#include <string>

int main() {
    std::string address;
    
    std::cout << "住所を入力:";
    std::cin >> address; // ❌ スペースで区切られる
    
    std::cout << "住所:" << address << std::endl;
    
    return 0;
}

解決: std::getline() を使用してください。


▶ サンプル 3:文字列検索と置換(難易度 ⭐⭐)

CPP
#include <iostream>
#include <string>

int main() {
    std::string text = "The quick brown fox jumps over the lazy dog";

    // "fox"を"cat"に検索して置換
    size_t pos = text.find("fox");
    if (pos != std::string::npos) {
        text.replace(pos, 3, "cat");
    }

    std::cout << text << std::endl;

    // "the"の出現回数をカウント(大文字小文字区別あり)
    int count = 0;
    pos = 0;
    while ((pos = text.find("the", pos)) != std::string::npos) {
        count++;
        pos++;
    }
    std::cout << "'the'の出現回数: " << count << std::endl;

    return 0;
}
▶ 試してみよう

出力:

TEXT 📖 参照専用
The quick brown cat jumps over the lazy dog
'the'の出現回数: 2

❓ よくある質問

Q: stringchar* の間で変換するには? A: 簡単に変換できます!

CPP
// string → char*
std::string s = "Hello";
const char* cstr = s.c_str(); // const char* を返す

// char* → string
const char* cstr = "Hello";
std::string s = cstr; // 自動変換

Q: 文字列操作を最適化するには? A: ループ内でのメモリ効率のため、std::stringstreamstd::string::reserve() を使用してください。

Q: string は日本語を扱える? A: はい!ただしソースファイルがUTF-8でエンコードされていることを確認してください。

CPP
std::string name = "こんにちは"; // 正常に動作
std::cout << name << std::endl;

📖 まとめ


📝 練習問題

  1. 初級(難易度 ⭐): ユーザー入力の文字列を受け取り、その長さを出力するプログラムを書いてください。

  2. 中級(難易度 ⭐⭐): ユーザー入力の文字列から、数字文字('0'-'9')だけを抽出して出力するプログラムを書いてください。

  3. 上級(難易度 ⭐⭐⭐): 簡易「図書管理システム」を実装してください:

    • string で本のタイトル、著者、ISBNを管理
    • 本の追加、検索、削除機能を実装
    • (オプション)ファイルへの保存


8. 🚀 次のステップ

string を理解したら、次は 構造体(struct)(レッスン21)——異なる型の変数をまとめて「クラス」のようなものを作ろう!

Web-Tutorial.com

Web-Tutorial 技術チーム

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

100%