C++入門|文字列を簡単に扱うstring

文字列修行をもっとやさしく。stringを覚えれば、C++の言葉あつかいは一気に戦いやすくなる。

ここまでの学習で、C++では数値をcinで受け取り、coutで表示できることを見てきました。
では、数字ではなく言葉を扱いたいときはどうすればよいのでしょうか。

たとえば、修行モードの名前、技の名前、戦士の名前、作戦コードのように、プログラムの中では文字の集まりを扱いたい場面がたくさんあります。
そんなときに活躍するのが、C++のstringです。

ドラゴンボールの世界観でたとえるなら、char型の配列で文字列を扱う方法は、1文字ずつ気の札を並べて巻物を作るようなやり方です。
仕組みはしっかりしていますが、1枚ずつ並べたり、終わりの印を付けたりと、少し手間がかかります。

それに対してstringは、文字列をひとまとまりの修行カプセルとして扱える便利な道具です。
cinやcoutとも相性がよく、文字列の入力や表示、連結や比較もぐっと分かりやすくなります。

ここでは、stringを使って文字列を入力・表示する方法、演算子を使った操作、char型の配列との違いまで、やさしく順番に見ていきましょう。

stringを使うと文字列はどう楽になるのか

C++では文字列を扱う方法がいくつかありますが、学習の初期段階で特に便利なのがstringです。
stringを使うと、文字列を1つのまとまりとして扱えます。

たとえば、char型の配列では「何文字入るか」「最後に文字列の終わりを示す印が必要か」といったことを意識する必要がありました。
一方でstringは、そうした細かい管理をかなり自動で引き受けてくれます。

扱い方イメージ学びやすさ
char型の配列文字を1つずつ並べる少し複雑
string文字列をひとまとまりで扱う分かりやすい

ドラゴンボール風にいえば、char型の配列は「文字の気弾を1発ずつ整列させる修行」です。
それに対してstringは、「文字列を1つの完成したエネルギーカプセルとして扱う修行」です。

そのため、文字列を入力する・表示する・つなげるといった基本操作が、とても自然な書き方でできます。

図:char型の配列とstringの違い

この図が示していること

この図から分かるのは、char型の配列が「文字を1つずつ並べて管理する方法」であるのに対し、stringは「文字列全体をひとまとまりとして扱える方法」だということです。

左側のchar型の配列では、1文字ごとに並びがあり、最後には文字列の終わりを表す印も必要になります。
一方、右側のstringは文字列全体を1つのまとまりとして扱えるので、入力や連結などの処理がずっと分かりやすくなります。

まずはstringを使ったサンプルを見てみよう

それでは、実際にstringを使ったプログラムを見てみましょう。
ここでは、修行で使うキーワードを入力し、その内容を表示するプログラムにしています。

プロジェクト/ファイル名: Chap2_04/main.cpp

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char** argv) {
    string keyword, message;

    // 表示用のメッセージを用意する
    message = "入力された修行キーワードは、";

    // 文字列を入力する
    cout << "修行キーワードを入力:";
    cin >> keyword;

    // 入力された文字列を表示する
    cout << message + keyword << "です。" << endl;

    return 0;
}

実行結果

修行キーワードを入力:Kamehameha
入力された修行キーワードは、Kamehamehaです。

このプログラムでは、keywordというstring型の変数に入力された文字列を入れています。
そしてmessageというstring型の変数に、あらかじめ表示したい文章を入れておき、最後に2つをつなげて表示しています。

見てのとおり、数値を扱うときのcinやcoutの書き方とほとんど同じです。
この分かりやすさが、stringの大きな魅力です。

stringを使うにはstringヘッダーが必要

stringを使うには、まず次の1行が必要です。

#include <string>

これは、stringを使うための準備です。
C++では、必要な機能を使うときに、対応するヘッダーを読み込みます。

今回のプログラムでは、表示や入力のためにiostreamを使い、文字列のためにstringを使っています。

ヘッダー役割
iostreamcin、coutを使うため
stringstringを使うため

ドラゴンボール風にたとえるなら、iostreamは入出力用の修行装置を呼び出す準備です。
stringは、文字列を扱うための専用カプセルを使えるようにする準備です。

string型の変数を宣言する

プログラムの中では、次のようにstring型の変数を宣言しています。

string keyword, message;

これは、keywordとmessageという2つのstring型変数を用意しているという意味です。

変数名役割
keyword入力された文字列を入れる
message表示用の文章を入れる

int型の変数が整数を入れる箱だったのと同じように、string型の変数は文字列を入れる箱です。

ドラゴンボール風にいえば、keywordとmessageは、言葉を入れておく修行カプセルです。
keywordには戦士が入力した言葉が入り、messageにはあらかじめ用意しておいた案内文が入ります。

=演算子で文字列を代入する

次に、この行を見てみましょう。

message = "入力された修行キーワードは、";

ここでは、=演算子を使って、messageに文字列を代入しています。

数値を代入するときと同じように、string型でも=演算子が使えます。
これはとても分かりやすいポイントです。

書き方意味
message = "入力された修行キーワードは、";messageに文字列を代入する

char型の配列で同じようなことをしようとすると、扱いが少し複雑になりがちです。
けれどstringなら、まるで普通の変数のように文字列を入れることができます。

ドラゴンボール風にたとえるなら、messageというカプセルに、案内文の気の巻物をそのまま入れているようなイメージです。

cinで文字列を入力できる

このプログラムの中で、文字列を入力しているのは次の行です。

cin >> keyword;

ここでは、キーボードから入力された文字列がkeywordに入ります。

数値の入力とまったく同じ形で書けるので、とても覚えやすいです。

書き方意味
cin >> keyword;入力した文字列をkeywordに入れる

実行すると、まず次のメッセージが表示されます。

cout << "修行キーワードを入力:";

すると入力待ちの状態になり、たとえば Kamehameha と入力してEnterを押すと、keywordにその文字列が入ります。

ドラゴンボール風にいえば、cinは修行端末に打ち込んだ技名を受け取り、keywordというカプセルに保存する装置です。

ただし、この形のcinは、空白で区切られた1語を受け取るのが基本です。
たとえば Super Saiyan Blue のように空白を含む入力では、最初のSuperまでが読み取られることがあります。
今の段階では、まず「空白のない文字列を入力する」と考えておくと分かりやすいです。

coutで文字列を表示する

入力した文字列を表示する部分が、次の行です。

cout << message + keyword << "です。" << endl;

ここでは、messageとkeywordをつなげて、その後ろにです。を付けて表示しています。

出力の流れを分解すると、次のようになります。

部分役割
message + keyword2つの文字列をつなげる
"です。"最後に付ける文章
endl改行する

つまり、入力が Kamehameha なら、次のような表示になります。

入力された修行キーワードは、Kamehamehaです。

数値のときと同じようにcoutを使えるので、文字列を扱うときも流れがとても自然です。

+演算子で文字列をつなげる

stringの便利さがよく表れているのが、+演算子です。

今回のプログラムでは、次のように使っています。

message + keyword

これは、messageの後ろにkeywordをつなげた新しい文字列を作る、という意味です。

結果のイメージ
"入力された修行キーワードは、"+ "Kamehameha""入力された修行キーワードは、Kamehameha"

C言語のchar型配列では、文字列同士をこのように+で直接つなげることはできません。
そのため、C++のstringは文字列操作がかなり楽になります。

ドラゴンボール風にたとえるなら、messageという巻物とkeywordという巻物を、1本の長い修行巻物として自然につなぎ合わせる感じです。

図:stringは+演算子で文字列をつなげられる

この図が示していること

この図から分かるのは、stringでは+演算子を使って文字列同士を自然につなげられるということです。

左側のメッセージ文字列と中央の入力文字列が、+によって1つの長い文字列になります。
この仕組みによって、表示文を組み立てる処理がとても分かりやすくなります。

string型で使える主な演算子

string型では、文字列に対していくつか便利な演算子が使えます。
ここでは、特によく使うものを整理しておきましょう。

演算子意味結果
+文字列同士をつなげるs1 + s22つの文字列が連結される
+=文字列を追加して代入するs += "Blue"元の文字列の後ろに追加される
==内容が同じか比較するs == "Blue"true または false
!=内容が違うか比較するs != "Blue"true または false
>辞書順で大きいか比較するs > "Blue"true または false
<辞書順で小さいか比較するs < "Blue"true または false

ここで出てくるtrueとfalseは、C++で使える真偽の値です。

  • true は「成り立つ」
  • false は「成り立たない」

という意味になります。

たとえば、sがBlueなら、

s == "Blue"

はtrueになります。
一方、sがRedならfalseになります。

ドラゴンボール風にいえば、比較演算は「この技名は一致しているか」「別の作戦コードか」を判定するスカウター判定のようなものです。

+=演算子も便利

+とあわせて覚えておきたいのが、+=演算子です。

これは、今ある文字列の後ろに文字列を追加して、その結果を元の変数に戻す書き方です。

たとえば、次のようなイメージです。

string form;
form = "Super";
form += "Saiyan";

この結果、formの中身は SuperSaiyan になります。

処理結果
form = "Super";Super
form += "Saiyan";SuperSaiyan

これは、次のような感覚で理解できます。

form = form + "Saiyan";

ただし、+=を使うほうが書き方がすっきりします。

stringの比較は文字列の内容を見てくれる

stringの便利なところは、比較も自然にできることです。

たとえば、

s == "Kamehameha"

と書けば、sの中身がKamehamehaかどうかを判定できます。

これは、char型の配列に比べてとても扱いやすいポイントです。

比較意味
s == "Fusion"sがFusionと同じか
s != "Fusion"sがFusionと違うか
s < "Fusion"辞書順でFusionより前か
s > "Fusion"辞書順でFusionより後か

ここでの大小比較は、数値の大きさではなく、文字列の並び順を比べるものです。
つまり、辞書に並べたときの順番のような比較です。

stringはC++のストリームと相性がよい

stringが特に学びやすい理由の1つが、cinやcoutと相性がよいことです。

今回のプログラムでも、

cin >> keyword;
cout << message + keyword << "です。" << endl;

という形で、とても自然に書けています。

数値のときと書き方が大きく変わらないので、入力と出力の流れをそのまま応用できます。

操作書き方
数値を入力するcin >> number;
文字列を入力するcin >> keyword;
数値を表示するcout << number << endl;
文字列を表示するcout << keyword << endl;

ドラゴンボール風にいえば、cinとcoutは修行場のデータ通路です。
その通路には数値も文字列も流せるので、stringを使うと文字列も同じ感覚で扱えるようになります。

図:stringはcinとcoutで自然に入出力できる

この図が示していること

この図では、stringがcinとcoutにそのままつながり、入力から出力までを自然な流れで扱えることを表しています。

左側で入力された文字列は、cinを通ってstring型の変数に入ります。
そのあと、coutによって結果が表示されます。

この流れは整数を扱うときととても似ているため、stringは初心者にも扱いやすい文字列の方法だと分かります。

char型の配列とstringの使い分け

C++では、char型の配列とstringのどちらも使われます。
それぞれに長所と短所があるので、場面に応じて使い分ける考え方が大切です。

char型の長所と短所

観点内容
長所必要とするメモリが少ない
長所処理スピードが速い
長所C言語の資産を活かしやすい
短所扱いが複雑で分かりにくい
短所エラーが起こりやすい

string型の長所と短所

観点内容
長所扱いが簡単で分かりやすい
長所エラーを起こしにくい
短所char型の配列より余分なメモリを使うことがある
短所char型の配列より処理がやや重くなることがある

この違いをドラゴンボール風にたとえると、char型の配列は「軽くて速いが、扱いに熟練が必要な昔ながらの修行具」です。
stringは「少し装備が大きい代わりに、扱いやすく安全な新型修行装置」です。

学習の最初はstringを味方にすると分かりやすい

学習の初期段階では、まずstringをしっかり使えるようになるのがおすすめです。

理由はとてもシンプルで、

  • 入力しやすい
  • 表示しやすい
  • つなげやすい
  • 比較しやすい

という、文字列にほしい機能が分かりやすくそろっているからです。

C++では、クラスという仕組みがこのあと重要になってきます。
stringもクラスから作られた仕組みですが、今の段階では、文字列を扱いやすくしてくれる便利な型として理解しておけば大丈夫です。

将来的にはchar型の配列も使いこなせるようになると、C++の文字列に対する理解はさらに深まります。
けれど、まずはstringで「文字列はこう扱えばいいんだ」と感覚をつかむことがとても大切です。

stringで押さえておきたいポイント

最後に、この内容で特に覚えておきたい点を整理しておきます。

ポイント内容
stringを使うには#include が必要
string型の変数文字列を入れるための変数
=演算子文字列を代入できる
cin文字列を入力できる
cout文字列を表示できる
+演算子文字列同士をつなげられる
+=演算子文字列を追加できる
== や !=内容の比較ができる
> や <文字列の並び順の比較ができる

stringを使えるようになると、C++で文字列を扱う世界がぐっと身近になります。
技名、戦士名、作戦コード、修行モード名など、これから先のプログラムでも文字列は何度も登場します。

文字列を簡単に扱えるstringは、C++の修行をスムーズに進める、とても頼もしい仲間です。