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;
}
戻り値の意味:
0:文字列が等しい< 0:呼び出し元が小さい> 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以降)
📝 練習問題
- 初級(難易度 ⭐):
ユーザー入力の文字列から空白を削除するプログラムを書いてください。TEXT 📖 参照専用
入力:Hello World, this is C++! 出力:HelloWorld,thisisC++!
2. **中級(難易度 ⭐⭐):**
ユーザー入力の文字列が「回文」かどうかを判定するプログラムを書いてください(前後逆にしても同じ、例:"level"、"radar")。
- ヒント:ポインタを使う方法、または反転して比較する方法があります。
3. **上級(難易度 ⭐⭐⭐):**
簡易「シーザー暗号」を実装してください:
- 暗号化:各文字のASCIIコードを3ずらす(例:`'A'` → `'D'`)
- 復号:各文字のASCIIコードを3戻す
- ユーザー入力の文字列を暗号化・復号して出力
---
---
## 7. 🚀 次のステップ
文字列の高度な操作を理解したら、次は **フェーズ4(ポインタと参照)** へ —— C++の「核」であり、メモリを直接操作する強力な機能を学ぼう!