文字列
テキストデータの効率的な管理。std::string の使い方
概要
C++で文字列を扱う方法は大きく分けて2つあります:
- C形式:
char arr[] = "Hello";(文字配列) - C++形式:
std::string str = "Hello";(推奨)
この章では、modern C++で標準的な
std::stringクラスを学びます。
std::string の基本
宣言と初期化
#include <iostream>
#include <string>
int main() {
std::string empty; // 空の文字列
std::string hello = "Hello"; // 初期化
std::string world("World"); // 別の書き方
std::string copies(5, '*'); // 5個の'*'で初期化 "****"
std::cout << hello << std::endl;
std::cout << world << std::endl;
std::cout << copies << std::endl;
return 0;
}
Hello
World
*****
文字列操作
連結(+演算子)
#include <iostream>
#include <string>
int main() {
std::string first = "Hello";
std::string second = "World";
std::string result = first + ", " + second + "!";
std::cout << result << std::endl;
return 0;
}
Hello, World!
長さ(length() / size())
#include <iostream>
#include <string>
int main() {
std::string text = "C++ Programming";
std::cout << "長さ: " << text.length() << std::endl;
std::cout << "サイズ: " << text.size() << std::endl;
return 0;
}
長さ: 15
サイズ: 15
インデックスアクセス
std::string text = "Hello";
std::cout << text[0] << std::endl; // 'H'
std::cout << text[1] << std::endl; // 'e'
text[0] = 'J';
std::cout << text << std::endl; // "Jello"
文字列の部分操作
部分文字列(substr)
#include <iostream>
#include <string>
int main() {
std::string text = "C++ Programming";
std::string part1 = text.substr(0, 3); // インデックス0から3文字 "C++"
std::string part2 = text.substr(4); // インデックス4から最後まで "Programming"
std::cout << part1 << std::endl;
std::cout << part2 << std::endl;
return 0;
}
C++
Programming
検索(find)
#include <iostream>
#include <string>
int main() {
std::string text = "Hello World";
size_t pos = text.find("World");
if (pos != std::string::npos) {
std::cout << "見つかった位置: " << pos << std::endl;
} else {
std::cout << "見つかりません" << std::endl;
}
return 0;
}
見つかった位置: 6
std::string::nposは「見つからない」を表すdinal値です。
文字列の追加と削除
追加(push_back、append)
#include <iostream>
#include <string>
int main() {
std::string text = "Hello";
text.push_back('!'); // 1文字追加
std::cout << text << std::endl; // "Hello!"
text.append(" World"); // 複数文字追加
std::cout << text << std::endl; // "Hello! World"
return 0;
}
Hello!
Hello! World
削除(pop_back、erase)
#include <iostream>
#include <string>
int main() {
std::string text = "Hello World";
text.pop_back(); // 最後の文字を削除
std::cout << text << std::endl; // "Hello Worl"
text.erase(5); // インデックス5以降を削除
std::cout << text << std::endl; // "Hello"
return 0;
}
Hello Worl
Hello
文字列の反復処理
例1: 各文字を出力
#include <iostream>
#include <string>
int main() {
std::string text = "C++";
// 範囲ベースの for ループ
for (char c : text) {
std::cout << c << " ";
}
std::cout << std::endl;
return 0;
}
C + +
例2: 文字数を数える
#include <iostream>
#include <string>
int main() {
std::string text = "programming";
int count = 0;
for (char c : text) {
if (c == 'p') {
count++;
}
}
std::cout << "'p'の個数: " << count << std::endl;
return 0;
}
'p'の個数: 2
実践例
例1: メールアドレスの検証
#include <iostream>
#include <string>
bool isValidEmail(const std::string & email) {
size_t at_pos = email.find('@');
if (at_pos == std::string::npos) return false;
size_t dot_pos = email.find('.', at_pos);
if (dot_pos == std::string::npos) return false;
return (at_pos > 0) && (dot_pos > at_pos + 1) && (dot_pos < email.length() - 1);
}
int main() {
std::string email1 = "user@example.com";
std::string email2 = "invalid-email";
std::cout << (isValidEmail(email1) ? "有効" : "無効") << std::endl;
std::cout << (isValidEmail(email2) ? "有効" : "無効") << std::endl;
return 0;
}
有効
無効
例2: 文字列の反転
#include <iostream>
#include <string>
int main() {
std::string original = "Hello World";
std::string reversed = original;
std::reverse(reversed.begin(), reversed.end());
std::cout << "元の文字列: " << original << std::endl;
std::cout << "反転後: " << reversed << std::endl;
return 0;
}
元の文字列: Hello World
反転後: dlroW olleH
文字列と数値の相互変換
#include <iostream>
#include <string>
int main() {
// 文字列 → 数値
std::string str1 = "42";
int num1 = std::stoi(str1); // stoi: string to int
std::string str2 = "3.14";
double num2 = std::stod(str2); // stod: string to double
std::cout << num1 * 2 << std::endl; // 84
std::cout << num2 * 2 << std::endl; // 6.28
// 数値 → 文字列
int value = 123;
std::string str3 = std::to_string(value);
std::cout << "数値: " << str3 << std::endl;
return 0;
}
84
6.28
数値: 123
ポイント
- std::stringは安全で使いやすい文字列クラス
+演算子で簡単に連結length()、substr()、find()などのメソッドが豊富- 範囲ベースの for ループで各文字に簡単アクセス
- 数値との相互変換は
std::stoi/std::to_stringを使用
よくある誤り
誤り1: インデックスを範囲外
std::string text = "Hello";
std::cout << text[10] << std::endl; // 危険!: 範囲外
誤り2: find()の戻り値をチェック忘れ
std::string text = "Hello";
size_t pos = text.find("x");
// npos チェックなしで pos を使用する
std::string sub = text.substr(pos); // 危険!
誤り3: C形式文字列との混同
std::string str = "Hello";
const char* c_str = str.c_str(); // OK
// ただし c_str はポインタなので注意が必要
やってみよう
練習1: ユーザーから文字列を入力させ、その長さを表示。
練習2: 文字列内の特定の文字をカウントする関数。
練習3: 文字列を逆順にするプログラム。
チャレンジ: 回文判定プログラム(例:"racecar")。
まとめ
- std::stringは modern C++の標準
- 豊富なメンバー関数で効率的に文字列操作
- 配列と異なり、サイズを動的に変更可能
- 安全性と使いやすさで C形式文字列に優れる