C言語の基本|C言語のエスケープシーケンスの基本

見えない記号の意味が分かれば、画面表示はもっと自由になる。エスケープシーケンスを使って、読みやすい出力を作ろう。

C言語のエスケープシーケンスの基本

printfで文字列を表示していると、文字をそのまま並べるだけでは表現できない場面が出てきます。

たとえば、次のような表示です。

  • 文章の途中で改行する
  • 項目の間にタブを入れる
  • バックスラッシュを表示する
  • 文字列の中にダブルクォーテーションを表示する
  • 文字列の終わりを示す

このような特殊な文字や動作を文字列の中で表すために、C言語ではエスケープシーケンスを使います。

エスケープシーケンスはバックスラッシュから始まり、その後ろに続く文字によって意味が決まります。代表的な\nは改行、\tはタブを表します。

ソースコード上では2文字の組み合わせに見えますが、C言語では1つの特殊な文字として扱われるのがポイントです。

エスケープシーケンスを理解すると、printfによる画面表示を読みやすく整えられるようになります。ファイルパスや引用符を含むメッセージも、正しい形で記述できます。

ここでは、使用頻度の高いエスケープシーケンスを中心に、それぞれの意味や書き方、間違えやすいポイントを確認していきましょう。

エスケープシーケンスとは

エスケープシーケンスは、文字列や文字定数の中で、特殊な文字や制御動作を表すための記述方法です。

基本的には、次の形になっています。

\ + 特定の文字

たとえば、バックスラッシュの後ろにnを書くと改行になります。

\n

バックスラッシュの後ろにtを書くと、水平タブになります。

\t

エスケープシーケンスには、主に次の役割があります。

  • 改行やタブなど、画面上で動作する制御文字を表す
  • バックスラッシュやダブルクォーテーションなど、特別な意味を持つ記号を表示する
  • 文字列の終わりを示すナル文字を表す

通常の文字と組み合わせて、printfの書式文字列でも使用できます。

printf("1行目\n2行目\n");

この文字列には、表示される文字と改行を表す\nが一緒に含まれています。

図1:エスケープシーケンスが特殊な動作に変わる仕組み

この図から分かること

エスケープシーケンスは、バックスラッシュと、その後ろに続く文字を組み合わせて作ります。

\nのように画面上の動作を表すものもあれば、\や"のように、本来は特別な意味を持つ記号を文字として表示するものもあります。

よく使うエスケープシーケンス

最初に覚えておきたいエスケープシーケンスは、次のとおりです。

表記意味主な用途
\n改行次の行へ移動する
\t水平タブ横方向に間隔を空ける
\バックスラッシュ文字として\を表示する
\"ダブルクォーテーション文字列中に"を表示する
\'シングルクォーテーション文字として'を表示する
\0ナル文字文字列の終端を表す

どれもソースコード上では複数の記号に見えますが、文字列の中では1つの特殊な文字として扱われます。

特に使用する機会が多いのは、次の4つです。

  • \nによる改行
  • \tによるタブ
  • \\によるバックスラッシュの表示
  • \"によるダブルクォーテーションの表示

改行を表す \n

\nは、表示位置を次の行へ移すエスケープシーケンスです。

printf("午前の学習\n午後の学習\n");

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

午前の学習
午後の学習

最初の\nによって、午前の学習を表示したあとに次の行へ移動します。2つ目の\nでは、午後の学習を表示したあとに改行します。

printfは、呼び出すだけでは自動的に改行しません。

printf("午前の学習");
printf("午後の学習");

この場合は、次のようにつながって表示されます。

午前の学習午後の学習

行を分けたい場合は、表示したい位置に\nを書きます。

printf("午前の学習\n");
printf("午後の学習\n");

\nを2回続けると空行を作れる

\nを2つ続けると、表示の間に空行を入れられます。

printf("最初の説明です\n\n");
printf("次の説明です\n");

実行結果は次のようになります。

最初の説明です

次の説明です

1つ目の\nで次の行へ移動し、2つ目の\nでもう一度改行します。その結果、2つの文章の間に何も表示されない行ができます。

表示する内容をグループごとに分けたい場合に便利です。ただし、空行を増やしすぎると画面が間延びするため、必要な場所だけで使うと読みやすくなります。

タブを表す \t

\tは水平タブを表します。表示位置を次のタブ位置まで進めるため、項目の間にまとまった空きを入れられます。

printf("科目\t点数\n");
printf("国語\t86\n");
printf("数学\t94\n");

実行結果のイメージは次のとおりです。

科目    点数
国語    86
数学    94

\tは、決められた個数の空白をそのまま入れるものではありません。現在の表示位置から、次のタブ位置まで移動します。

そのため、項目名の長さが大きく異なると、列がそろわない場合があります。

printf("国語\t86\n");
printf("プログラミング基礎\t94\n");

実行環境によっては、2行目の点数が1行目より右側にずれて表示されます。

簡単な一覧なら\tで十分ですが、列を細かく整える必要がある場合は、printfの表示幅を指定する方法もあります。まずは、\tが横方向の区切りに使えることを覚えておきましょう。

バックスラッシュを表示する \

バックスラッシュは、エスケープシーケンスの開始を表す記号です。そのため、文字列の中にバックスラッシュを1つだけ書くと、後ろの文字と組み合わされて別の意味になる可能性があります。

バックスラッシュそのものを表示したい場合は、2つ続けて\と書きます。

printf("バックスラッシュは \\ です\n");

実行結果では、バックスラッシュが1つ表示されます。

バックスラッシュは \ です

ソースコードと実行結果の違いを整理すると、次のようになります。

ソースコード内の表記画面に表示される内容
\後ろの文字と組み合わされて別の意味になる可能性がある
\\\

ソースコード上では、表示したいバックスラッシュ1文字につき\を書く必要があります。

Windowsのパスを表示する

Windowsのパスにはバックスラッシュが使われています。

C:\Work\CStudy

このパスをprintfで表示する場合は、それぞれのバックスラッシュを\と書きます。

printf("保存先: C:\\Work\\CStudy\n");

実行結果は次のようになります。

保存先: C:\Work\CStudy

次のようにバックスラッシュを1つだけ書くのは避けましょう。

printf("保存先: C:\Work\CStudy\n");

\Wや\Cは、C言語で定義された正しいエスケープシーケンスではありません。コンパイラから警告が出たり、意図しない文字列として扱われたりする可能性があります。

Windowsのパスを文字列に書くときは、バックスラッシュを\に置き換えると覚えておくと安心です。

ダブルクォーテーションを表示する "

C言語の文字列は、ダブルクォーテーションで囲みます。

printf("C言語を学習します\n");

文字列の中にダブルクォーテーションをそのまま書くと、コンパイラはそこで文字列が終わったと判断します。

次の書き方は正しくありません。

printf(""C言語"を学習します\n");

画面にダブルクォーテーションを表示したい場合は、"を使います。

printf("\"C言語\"を学習します\n");

実行結果は次のとおりです。

"C言語"を学習します

最初の"は開始側のダブルクォーテーション、2つ目の"は終了側のダブルクォーテーションとして表示されます。

図2:Windowsのパスと引用符を正しく表示する方法

この図から分かること

バックスラッシュとダブルクォーテーションは、C言語の文字列内で特別な役割を持っています。

バックスラッシュを表示する場合は\、ダブルクォーテーションを表示する場合は"と書きます。ソースコードでは2文字に見えても、実行結果ではそれぞれ1つの記号として表示されます。

シングルクォーテーションを表示する '

シングルクォーテーションを表すエスケープシーケンスは'です。

printf("文字定数の例は \'A\' です\n");

実行結果は次のようになります。

文字定数の例は 'A' です

ダブルクォーテーションで囲まれた文字列の中では、シングルクォーテーションをそのまま書くこともできます。

printf("文字定数の例は 'A' です\n");

この書き方でも同じ結果になります。

一方、シングルクォーテーションで囲む文字定数の中に、シングルクォーテーションそのものを書く場合は、エスケープが必要です。

char mark = '\'';

この宣言では、markにシングルクォーテーション1文字を保存しています。

用途によって必要性は異なりますが、'がシングルクォーテーションを表す書き方だと知っておくと、文字定数を扱うときにも役立ちます。

ナル文字を表す \0

\0は、値が0の文字を表すエスケープシーケンスです。この文字をナル文字といいます。

ナル文字は、画面に形が表示される文字ではありません。C言語では、主に文字列の終わりを示すために使われます。

たとえば、文字列ABCは、メモリ上では次のように保存されます。

['A']['B']['C']['\0']

文字列リテラルを記述すると、末尾の\0はコンパイラによって自動的に追加されます。

"ABC"

そのため、通常は次のように自分で\0を追加する必要はありません。

"ABC\0"

文字列ABCを保存するには、見える3文字に加えて、終端を示す\0の領域も必要です。

要素内容
1文字目A
2文字目B
3文字目C
4文字目\0

printfで%sを使って文字列を表示するときも、ナル文字を手がかりにして文字列の終わりを判断します。

printf("%s\n", "ABC");

\0自体は画面に表示されません。文字列の範囲を知らせる、見えない目印として働きます。

エスケープシーケンスをまとめて使ってみよう

ここまでに確認したエスケープシーケンスを、1つのプログラムで使ってみましょう。

学習記録を見やすく表示するプログラム

ファイル名:5_2_1.c

#include <stdio.h>

int main(void)
{
    /* タブを使って学習記録を表示する */
    printf("項目\t内容\n");
    printf("教材\tC言語入門\n");
    printf("時間\t40分\n");

    /* Windowsの保存先を表示する */
    printf("保存先: C:\\cwork\\chap05\\record.txt\n");

    /* ダブルクォーテーションを含む文章を表示する */
    printf("今日の目標は\"エスケープシーケンスを覚える\"です\n");

    /* シングルクォーテーションを表示する */
    printf("文字定数の例は \'B\' です\n");

    /* 改行を2回行い、空行を入れる */
    printf("学習記録を保存しました\n\n");
    printf("次の学習へ進みましょう\n");

    return 0;
}
実行結果の例
項目    内容
教材    C言語入門
時間    40分
保存先: C:\cwork\chap05\record.txt
今日の目標は"エスケープシーケンスを覚える"です
文字定数の例は 'B' です
学習記録を保存しました

次の学習へ進みましょう

プログラムの内容を詳しく確認しよう

最初の3つのprintfでは、\tと\nを組み合わせています。

printf("項目\t内容\n");
printf("教材\tC言語入門\n");
printf("時間\t40分\n");

\tによって、項目名と内容の間に横方向の間隔を入れています。各行の最後にある\nによって、1件表示するたびに次の行へ移動します。

次のprintfでは、Windowsのパスを表示しています。

printf("保存先: C:\\cwork\\chap05\\record.txt\n");

コード上の\は、実行結果では1つのバックスラッシュとして表示されます。

ソースコード上実行結果
C:\cworkC:\cwork
\chap05\chap05
\record.txt\record.txt

次の行では、文章の一部をダブルクォーテーションで囲んでいます。

printf("今日の目標は\"エスケープシーケンスを覚える\"です\n");

文字列全体を囲むダブルクォーテーションと、画面に表示するダブルクォーテーションは役割が異なります。表示したいほうにはバックスラッシュを付けて、"と記述します。

シングルクォーテーションは、次の行で表示しています。

printf("文字定数の例は \'B\' です\n");

この文字列では、'を使わずに'B'と書くこともできます。ただし、'の意味を確認できるように、エスケープした形で記述しています。

最後の部分では、\nを2つ続けています。

printf("学習記録を保存しました\n\n");
printf("次の学習へ進みましょう\n");

最初の\nで学習記録を保存しましたの次の行へ移り、2つ目の\nでもう一度改行します。そのため、次のメッセージとの間に空行が1行入ります。

文字列を分解して読んでみよう

エスケープシーケンスが多い文字列は、最初は読みにくく感じるかもしれません。その場合は、通常の文字とエスケープシーケンスに分けて考えると分かりやすくなります。

次のコードを例にします。

printf("C:\\cwork\\chap05\\record.txt\n");

左から順番に分けると、次のようになります。

コード上の部分意味
C:Cドライブを表す通常の文字
\バックスラッシュを1つ表示
cwork通常の文字列
\バックスラッシュを1つ表示
chap05通常の文字列
\バックスラッシュを1つ表示
record.txt通常の文字列
\n最後に改行

頭の中では、次のように読むとよいでしょう。

C:
バックスラッシュ
cwork
バックスラッシュ
chap05
バックスラッシュ
record.txt
改行

エスケープシーケンスを1つのまとまりとして見ると、文字列全体の意味を追いやすくなります。

図3:文字列の中からエスケープシーケンスを読み取る

この図から分かること

文字列のすべてがエスケープシーケンスになるわけではありません。通常の文字はそのまま表示され、\はバックスラッシュに、最後の\nは改行に変わります。

長い文字列も、通常の部分とバックスラッシュから始まる部分に分ければ、意味を確認しやすくなります。

よくある間違いを確認しよう

エスケープシーケンスでは、バックスラッシュの付け忘れや記号の重ね方による間違いが起こりやすくなります。

Windowsのパスをそのまま書いてしまう

次のコードでは、パス内のバックスラッシュが1つだけになっています。

printf("C:\Temp\memo.txt\n");

この書き方では、\Tや\mが正しくないエスケープシーケンスとして扱われる可能性があります。

正しくは、すべてのバックスラッシュを\と書きます。

printf("C:\\Temp\\memo.txt\n");

ダブルクォーテーションをそのまま入れてしまう

次のコードでは、C言語の前にあるダブルクォーテーションによって、文字列が終了したように解釈されます。

printf(""C言語"を学びます\n");

表示用のダブルクォーテーションには、バックスラッシュを付けます。

printf("\"C言語\"を学びます\n");

改行を入れ忘れる

次のコードには\nがないため、2つのメッセージが同じ行に表示されます。

printf("処理を開始します");
printf("ファイルを確認します");

行を分けたい場合は、適切な位置に\nを追加します。

printf("処理を開始します\n");
printf("ファイルを確認します\n");

バックスラッシュを必要以上に増やす

画面にバックスラッシュを1つ表示するには、コード上で\と書きます。

printf("\\\n");

ここでは、最初の\がバックスラッシュ1文字を表し、最後の\nが改行を表しています。

一方、次のようにバックスラッシュを4つ書くと、画面には2つ表示されます。

printf("\\\\\n");

\\

バックスラッシュの数が分かりにくくなったときは、左から2つずつ区切って確認しましょう。

\0と数字の0を混同しないようにしよう

\0はナル文字ですが、数字の文字である0とは異なります。

表記意味
0数字として書かれた整数定数
'0'数字の形をした文字
'\0'値が0のナル文字
"\0"ナル文字を含む文字列リテラル

'0'は画面に表示できる数字の文字です。一方、'\0'は文字列の終端などに使われる、画面には見えない文字です。

printf("%c\n", '0');

この場合は、数字の0が表示されます。

ナル文字は文字列の終わりを示すため、通常の表示文字として使うものではありません。この違いは、今後、文字配列や文字列処理を学ぶときに重要になります。

エスケープシーケンスを使うときの確認ポイント

文字列を記述したあとに、次の点を確認すると間違いを見つけやすくなります。

  • 改行したい位置に\nがあるか
  • タブを入れたい位置に\tがあるか
  • バックスラッシュを\\と書いているか
  • 表示用のダブルクォーテーションを\"と書いているか
  • 文字列の開始と終了のダブルクォーテーションが対応しているか
  • 意図しないエスケープシーケンスが含まれていないか
  • 文末のセミコロンを忘れていないか

最初は、文字列の中にバックスラッシュが増えると複雑に見えるかもしれません。まずは \n、\t、\\、"の4つを優先して、短いprintfで動作を確認してみるのがおすすめです。

これらを使えるようになると、改行を含む案内メッセージ、簡単な一覧、Windowsのファイルパス、引用符を含む文章などを、意図した形で表示できるようになります。