C++入門|C++の文字列

文字列は、文字という小さな気の粒を並べたメッセージ巻物。char配列とstringクラスを理解して、C++で言葉を自在に扱えるようになろう。

ここまで、C++ではcinやcoutを使って、数値の入力や表示を行ってきました。

次に学ぶのは、文字列です。

文字列とは、複数の文字が並んだデータのことです。
たとえば、Training、HelloWorld、C++ Start のように、文字がまとまって意味を持つものが文字列です。

ドラゴンボール風にたとえるなら、1文字は小さな気の粒です。
その気の粒を順番に並べると、技名や修行メッセージが書かれた巻物になります。
この巻物のようなものが、プログラムでいう文字列です。

C++で文字列を扱う方法は、大きく分けて2つあります。

方法特徴ドラゴンボール風のイメージ
char型の配列C言語由来の文字列の扱い方1文字ずつ並べた古い修行巻物
stringクラスC++で使いやすい文字列の扱い方文字列をまとめて扱える新しい修行カプセル

まずは、C言語から受け継いだchar型の配列による文字列の扱いを見ていきます。

C++ではC言語の仕組みも使えるため、char型の配列で文字列を扱う方法を理解しておくと、C++の土台がよりしっかりします。
そのうえで、C++らしいstringクラスを使う方法へ進むと、文字列の扱いがかなり分かりやすくなります。

C++で文字列を扱う2つの方法

C++では、文字列を扱う方法として、C言語由来のchar型配列と、C++で用意されたstringクラスがあります。

char型配列は、文字を1つずつ配列に入れて管理する方法です。
C言語では、この方法で文字列を扱います。

一方、stringクラスは、C++で文字列を扱いやすくするために用意された仕組みです。
文字列全体を1つのまとまりとして扱いやすく、C++のプログラムではよく使われます。

比較項目char型配列stringクラス
言語の背景C言語由来C++でよく使う
扱い方文字を配列に並べる文字列を1つのオブジェクトとして扱う
終端の考え方最後にNULL文字が必要内部で管理される
初心者の扱いやすさ仕組みの理解が必要比較的扱いやすい
学習上の重要性C言語とのつながりを理解できるC++らしい文字列操作につながる

ドラゴンボール風に言えば、char型配列は昔ながらの修行巻物です。
1文字ずつきっちり並べ、最後にここで終わりという印を付けます。

stringクラスは、新しい修行カプセルです。
文字列をまとめて入れておけるので、扱いやすく、C++らしい書き方に向いています。

図:C++の文字列には2つの扱い方がある

この図が示していること

この図では、C++で文字列を扱う方法が2つあることを表しています。

左側のchar型配列は、文字を1つずつ並べ、最後に文字列の終わりを示すNULL文字を置く方法です。
右側のstringクラスは、文字列を1つのまとまりとして扱いやすくするC++らしい方法です。

まずchar型配列の仕組みを理解しておくと、C言語とのつながりや、文字列が内部でどのように並んでいるのかをイメージしやすくなります。

char型配列を使った文字列のプログラム

まずは、char型の配列を使って文字列を表示するプログラムを見てみましょう。

ここでは、短い修行コードと、修行モード名を文字列として用意し、printfとcoutの両方で表示します。

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

#include <iostream>
#include <stdio.h>

using namespace std;

// char型配列で文字列を扱うサンプル
int main(int argc, char** argv) {
    // 1文字ずつ並べて文字列を作る
    char code[] = { 'K', 'i', '\0' };

    // 文字列リテラルでchar型配列を初期化する
    char mode[] = "TrainingMode";

    // printfで文字列を表示する
    printf("== printfで表示 ==\n");
    printf("code = %s\n", code);
    printf("mode = %s\n", mode);

    // coutで文字列を表示する
    cout << "== coutで表示 ==" << endl;
    cout << "code = " << code << endl;
    cout << "mode = " << mode << endl;

    // プログラムが正常に終わったことを示す
    return 0;
}

実行すると、次のように表示されます。

== printfで表示 ==
code = Ki
mode = TrainingMode
== coutで表示 ==
code = Ki
mode = TrainingMode

このプログラムでは、codeとmodeという2つのchar型配列を使っています。

codeは、1文字ずつ配列に入れて文字列を作っています。
modeは、文字列リテラルを使って、まとめて初期化しています。

配列名作り方表示される文字列
code1文字ずつ並べるKi
mode文字列リテラルで初期化するTrainingMode

ドラゴンボール風にたとえるなら、codeは1文字ずつ気の粒を並べて作った短い合図です。
modeは、最初からTrainingModeという修行名が書かれた巻物です。

char型は1文字を扱うための型

C言語やC++では、1文字を扱うためにchar型を使います。

たとえば、次のように書くと、変数markに文字Kを入れることができます。

char mark = 'K';

文字を表すときは、シングルクォーテーションで1文字を囲みます。

一方、複数の文字が並んだ文字列は、ダブルクォーテーションで囲みます。

種類意味
文字char mark = 'K';1文字だけを扱う
文字列char mode[] = "TrainingMode";複数の文字をまとめて扱う

コンピュータの中では、文字も数値として扱われます。
たとえば、アルファベットや数字、記号には、それぞれ対応する文字コードがあります。

char型には、文字そのものが入っているように見えますが、内部的には文字を表す数値が入っています。

ドラゴンボール風にたとえるなら、文字は見た目の技名ですが、修行装置の内部ではそれぞれの文字が番号付きの気の信号として扱われています。

ASCIIコードとは何か

ASCIIコードは、アルファベット、数字、記号、空白、制御文字などを数値で表すための基本的な文字コードです。

C言語のchar型を理解するとき、ASCIIコードの考え方はとても重要です。

たとえば、AやBといった文字は、コンピュータの中では決められた数値として扱われます。
人間には文字として見えていますが、コンピュータにとっては文字コードという数値です。

文字イメージ
A文字コードとして管理される
B文字コードとして管理される
0数字の文字として管理される
空白空白を表す文字コードとして管理される

ASCIIコードは、7ビットで表される基本的な文字コードで、0から127までの範囲で文字を表します。

ドラゴンボール風にたとえるなら、ASCIIコードは文字ごとに割り当てられたスカウター番号です。
Aという文字にはA用の番号、Bという文字にはB用の番号があり、修行装置はその番号を見て文字を判断しています。

char型配列で文字列を作る仕組み

char型配列で文字列を作る場合、文字を1つずつ配列に並べます。

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

char code[] = { 'K', 'i', '\0' };

これは、codeという配列に、K、i、文字列の終わりを表すNULL文字を入れているという意味です。

添え字中身意味
code[0]K1文字目
code[1]i2文字目
code[2]\0文字列の終わり

ここで重要なのが、最後の\0です。

\0は、NULL文字、またはヌル終端文字と呼ばれます。
char型配列で文字列を扱う場合、この\0によって、ここで文字列が終わると判断されます。

つまり、Kiという2文字の文字列を作るには、K、iの2文字に加えて、終わりを示す\0が必要です。
そのため、最低でも3つの要素が必要になります。

図:char型配列の最後にはNULL文字が必要

この図が示していること

この図では、char型配列で文字列を作るとき、最後にNULL文字が必要になることを表しています。

code[0]にK、code[1]にiが入っています。
そしてcode[2]に\0が入ることで、文字列はここで終わりだと判断されます。

char型配列では、文字そのものだけでなく、文字列の終わりを示す印も必要です。
この仕組みを理解しておくと、C言語由来の文字列の扱いが分かりやすくなります。

NULL文字は文字列の終わりを示す印

NULL文字は、文字列の終わりを示す特別な文字です。

'\0'

値としては0に相当しますが、文字列の中では、ここで文字列が終わるという合図として使われます。

char型配列で文字列を表示するとき、printfやcoutは先頭から文字を読んでいきます。
そして\0に出会うと、そこで読み取りを止めます。

ドラゴンボール風にたとえるなら、\0は巻物の終わりに押される終了印です。

もし終了印がなければ、修行装置はどこまで読めばよいのか分からなくなってしまいます。
そのため、char型配列で文字列を作るときは、最後に\0が必要です。

文字列実際に必要な要素
KiK、i、\0
abca、b、c、\0
HelloH、e、l、l、o、\0

文字数が2なら、配列には最低3要素が必要です。
文字数が5なら、配列には最低6要素が必要です。

つまり、char型配列で文字列を入れるには、文字数 + 1 の大きさが必要になります。

ダブルクォーテーションで文字列を初期化する

char型配列に文字列を入れるとき、毎回1文字ずつ書くのは少し大変です。

そこで、次のようにダブルクォーテーションを使って初期化できます。

char mode[] = "TrainingMode";

この書き方をすると、C++が自動的に文字を1つずつ配列に入れ、最後に\0も追加してくれます。

TrainingModeは12文字です。

添え字中身
mode[0]T
mode[1]r
mode[2]a
mode[3]i
mode[4]n
mode[5]i
mode[6]n
mode[7]g
mode[8]M
mode[9]o
mode[10]d
mode[11]e
mode[12]\0

文字列そのものは12文字ですが、最後に\0が入るため、内部では13個分の要素が必要です。

ただし、char mode[] = "TrainingMode"; のように[]の中の数を省略すれば、必要な要素数を自動で用意してくれます。

ドラゴンボール風にたとえるなら、修行巻物にTrainingModeとまとめて書くと、修行装置が自動的に1文字ずつカプセルへ分けて、最後に終了印を付けてくれるようなものです。

printfで文字列を表示する

char型配列の文字列は、C言語のprintfでも表示できます。

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

printf("code = %s\n", code);
printf("mode = %s\n", mode);

printfで文字列を表示するときは、%sを使います。

書式指定意味
%s文字列を表示する
\n改行する

printf("code = %s\n", code); では、%sの部分にcodeの文字列が入ります。

そのため、次のように表示されます。

code = Ki

同じように、modeも文字列として表示されます。

mode = TrainingMode

ドラゴンボール風にたとえるなら、%sは表示パネルの文字列用の空欄です。
その空欄に、codeやmodeの文字列が入って表示されます。

coutでもchar型配列の文字列を表示できる

C++では、coutを使ってchar型配列の文字列を表示することもできます。

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

cout << "code = " << code << endl;
cout << "mode = " << mode << endl;

coutでは、文字列や変数を<<で順番に送って表示します。

記述意味
coutコンソールへの出力
<<データをcoutへ送る
"code = "表示する文字列
codechar型配列の内容
endl改行する

C言語のprintfでは%sや\nを使いました。
C++のcoutでは、表示したいものを<<でつないでいきます。

表示方法書き方
printfprintf("code = %s\n", code);
coutcout << "code = " << code << endl;

どちらでも同じように文字列を表示できます。

ただし、C++のプログラムでは、coutを使う書き方に慣れておくと、数値や文字列を自然につないで表示しやすくなります。

printfとcoutの違いを整理する

printfとcoutは、どちらもコンソールに文字列を表示できます。

ただし、考え方が少し違います。

printfは、表示の形を文字列の中に指定し、あとから値を渡す方法です。
coutは、出力したいデータを<<で順番に流していく方法です。

項目printfcout
主な背景C言語由来C++でよく使う
文字列の表示%sを使う<<でつなぐ
改行\nを使うendlまたは\nを使う
書き方のイメージ表示の型に値をはめるデータを出力ストリームへ送る

ドラゴンボール風にたとえるなら、printfは決められた表示枠に文字列をはめ込む古い表示装置です。
coutは、表示したいデータを順番に流し込める新しいストリーム装置です。

どちらも使えますが、C++の学習ではcoutの使い方に慣れていくことが大切です。

図:printfとcoutで文字列を表示する流れ

この図が示していること

この図では、printfとcoutのどちらでもchar型配列の文字列を表示できることを表しています。

printfでは、%sを使って文字列を表示します。
coutでは、<<を使って文字列や変数を順番に出力します。

C++ではcoutを使う場面が多くなりますが、C言語由来の文字列を理解するためには、printfでの表示方法も知っておくと役立ちます。

char型配列で入力するときは注意が必要

char型配列は、文字列を保存したり表示したりできます。

ただし、キーボードから文字列を入力してchar型配列へ入れる場合は、配列の大きさを超えないように注意が必要です。

たとえば、配列の大きさが小さいのに長い文字列を入力すると、用意した場所を超えてしまう危険があります。

ドラゴンボール風にたとえるなら、小さな修行カプセルに長すぎる巻物を無理やり入れようとするようなものです。
入りきらない部分が周りの装置に影響してしまう可能性があります。

そのため、C++で文字列を入力して扱う場合は、stringクラスを使う方法が扱いやすくなります。

stringクラスを使った文字列

C++には、文字列を扱いやすくするためのstringクラスがあります。

stringを使うと、文字列を1つのまとまりとして扱えます。

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

string message = "TrainingMode";

stringクラスを使う場合は、通常string用のヘッダーを読み込みます。

#include <string>

stringは、char型配列よりも扱いやすく、C++らしい文字列の書き方です。

比較項目char型配列stringクラス
文字列の終端\0を意識する基本的には自動で管理される
文字列の扱いやすさ配列サイズに注意が必要扱いやすい
C言語との関係C言語由来C++らしい方法
学習での位置づけ文字列の内部構造を理解できる実用的な文字列操作につながる

オブジェクト指向の言葉で見ると、stringはクラスです。
そして、string messageのように作られたmessageは、文字列を扱うオブジェクトとして考えることができます。

ドラゴンボール風にたとえるなら、stringクラスは文字列を扱うための設計図です。
そこから作られたmessageは、実際に文字列を入れて使える修行カプセルです。

このあとC++の学習が進むと、クラスやオブジェクトの考え方がさらに重要になります。
今は、stringはC++で文字列を扱いやすくするための便利な仕組みだと覚えておきましょう。

char型配列とstringクラスを使い分ける

C++では、char型配列とstringクラスのどちらも使う場面があります。

C言語との互換性が必要な場面や、文字列の内部構造を理解したい場面では、char型配列の知識が役立ちます。
一方、C++らしく文字列を扱いたい場合は、stringクラスが便利です。

使いたい場面向いている方法
C言語の文字列の仕組みを理解したいchar型配列
printfと組み合わせて扱いたいchar型配列
C++らしく文字列を扱いたいstringクラス
文字列の入力や加工を扱いやすくしたいstringクラス

学習の流れとしては、まずchar型配列で文字列がどう並んでいるのかを理解し、そのあとstringクラスで便利に扱う方法を学ぶのがおすすめです。

C++の文字列で覚えておきたいポイント

C++の文字列では、次のポイントを押さえておきましょう。

ポイント内容
char型は1文字を扱う文字は内部で文字コードとして管理される
char型配列で文字列を作れる文字を配列に並べて扱う
最後に\0が必要文字列の終わりを示す
文字数 + 1の要素が必要NULL文字の分を含める
ダブルクォーテーションで初期化できる自動的に\0が付く
printfでは%sで表示するchar型配列の文字列を表示できる
coutでも表示できる<<を使って出力できる
stringクラスも使えるC++らしい文字列の扱い方

文字列は、プログラムでとてもよく使います。

名前、メッセージ、ファイル名、コマンド、説明文など、文字列を扱う場面はたくさんあります。

C++では、C言語由来のchar型配列と、C++らしいstringクラスの両方を知っておくことが大切です。

ドラゴンボール風に言えば、char型配列は1文字ずつ並べた古い修行巻物、stringクラスは文字列をまとめて扱える新しい修行カプセルです。

まずはchar型配列で文字列の基本構造を理解し、そのうえでstringクラスへ進むと、C++の文字列がぐっと扱いやすくなります。