C言語の基本|printfで文字と文字列を表示する

文字と文字列を正しく使い分ければ、画面表示はもっと伝わりやすくなる。printfの%c、%s、%%を覚えて、分かりやすいメッセージを作ろう。

printfで文字と文字列を表示する

C言語のプログラムでは、計算結果だけでなく、案内文、メニュー、エラーメッセージなど、さまざまな文字情報を画面に表示します。

たとえば、次のような場面です。

  • 利用者に操作方法を説明する
  • 入力してほしい内容を案内する
  • 計算結果に見出しを付ける
  • 1文字の評価記号を表示する
  • 作業の進み具合をパーセントで表示する

このような表示にもprintfを使います。

printfでは、表示するデータの種類に合わせて書式指定を選びます。1文字には%c、文字列には%s、パーセント記号には%%を使用します。

printf("評価は%cです\n", 'A');
printf("結果は%sです\n", "合格");
printf("達成率は90%%です\n");

文字と文字列は見た目が似ていますが、C言語では別のデータです。この違いを理解すると、printfの書式指定を正しく選べるようになります。

文字と文字列の違い

C言語における文字は、基本的に1文字だけを表します。文字列は、0文字以上の文字が順番に並んだデータです。

比較項目文字文字列
表すもの1文字0文字以上の文字の並び
囲む記号シングルクォーテーションダブルクォーテーション
記述例Aを表す文字定数ABCを表す文字列リテラル
printfの書式指定%c%s

コードでは、次のように書き分けます。

'A'      /* 文字 */
"ABC"    /* 文字列 */

文字Aはシングルクォーテーションで囲みます。

'A'

文字列ABCはダブルクォーテーションで囲みます。

"ABC"

文字列は、1文字だけで構成することもできます。

"A"

ただし、文字Aと文字列Aは同じものではありません。

'A'    /* 1文字 */
"A"    /* 文字列 */

printfで表示するときも、異なる書式指定を使用します。

printf("%c\n", 'A');
printf("%s\n", "A");

どちらも画面にはAと表示されますが、printfへ渡しているデータの種類が異なります。

図1:文字と文字列の違い

この図から分かること

文字Aは1文字のデータですが、文字列Aは文字の並びとして扱われます。

文字には%c、文字列には%sを使います。画面上で同じAに見えても、C言語の内部では異なるデータであることが分かります。

コンピュータの内部では文字も数値として扱われる

コンピュータは文字を数値に対応させて管理しています。この対応に使われるのが文字コードです。

たとえば、一般的なASCIIコードでは、英大文字のAに65という値が割り当てられています。

表示される文字:A
対応する値  :65

char型の変数に文字Aを保存する場合は、次のように書きます。

char grade = 'A';

printfで%cを使うと、gradeに保存されている値を文字として表示できます。

printf("%c\n", grade);

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

A

%cを使うことで、内部の値を通常の整数ではなく、対応する文字として表示できます。

今回使用する書式指定

文字、文字列、パーセント記号の表示には、次の書式指定を使います。

書式指定表示するもの対応するデータ
%c1文字文字定数やchar型の変数
%s文字列文字列リテラルなど
%%パーセント記号対応する値は不要

%cと%sには、対応する値を引数として渡します。

printf("%c\n", 'A');
printf("%s\n", "Hello");

%%はパーセント記号そのものを表示するための特別な指定です。表示する値を後ろに渡す必要はありません。

printf("達成率は80%%です\n");

%cで1文字を表示する

%cは、1文字を表示するための書式指定です。

printf("評価は%cです\n", 'B');

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

評価はBです

書式文字列にある%cと、後ろに渡した文字Bが対応しています。

%c ← 文字B

char型の変数も表示できます。

char symbol = '#';

printf("記号は%cです\n", symbol);

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

記号は#です

複数の文字を表示する

1つのprintfに複数の%cを書けば、複数の文字を表示できます。

printf("%c %c %c\n", 'A', 'B', 'C');

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

A B C

書式指定と値は、左から順番に対応します。

順番書式指定対応する文字表示結果
1%cAA
2%cBB
3%cCC

%cが3つあるため、後ろにも文字を3つ渡しています。

書式文字列内にある空白も、そのまま画面に表示されます。

printf("%c %c %c\n", 'A', 'B', 'C');

空白を入れずに続けて表示する場合は、次のようにします。

printf("%c%c%c\n", 'A', 'B', 'C');

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

ABC

改行も1文字として扱われる

改行を表す\nは、エスケープシーケンスです。ソースコード上ではバックスラッシュとnの組み合わせに見えますが、C言語では改行を表す1文字として扱われます。

そのため、%cを使って表示することもできます。

printf("1行目%c2行目%c", '\n', '\n');

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

1行目
2行目

ただし、通常は次のように書式文字列の中へ\nを書くほうが分かりやすいでしょう。

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

%sで文字列を表示する

%sは、文字列を表示するための書式指定です。

printf("状態は%sです\n", "準備完了");

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

状態は準備完了です

%sには、後ろに渡した文字列が入ります。

%s ← 文字列の準備完了

文字列リテラルをそのままprintfへ渡すこともできます。

printf("%s\n", "C言語を学習しています");

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

C言語を学習しています

文字列をそのまま表示するだけなら、次のように書くこともできます。

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

%sは、文字列の一部を後から変更したい場合や、文字列を保存したデータを表示する場合に便利です。

複数の文字列を組み合わせる

1つのprintfに複数の%sを指定できます。

printf("%s %s\n", "Good", "Morning");

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

Good Morning

1つ目の%sにはGood、2つ目の%sにはMorningが対応します。

順番書式指定対応する文字列
1%sGood
2%sMorning

%sの間に書かれた空白は、そのまま表示されます。

日本語の文字列を空白なしで続ける場合は、次のように書けます。

printf("%s%s\n", "おはよう", "ございます");

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

おはようございます

空白を入れたい場合は、書式文字列側に空白を記述します。

printf("%s %s\n", "おはよう", "ございます");

おはよう ございます

%s はナル文字までを表示する

C言語の文字列には、終わりを表すナル文字\0が付いています。

文字列ABCは、内部では次のように並んでいます。

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

printfで%sを使うと、文字列の先頭から順番に文字を読み取ります。

Aを表示
  ↓
Bを表示
  ↓
Cを表示
  ↓
\0を見つけて終了

ナル文字自体は画面に表示されません。printfに文字列の終わりを知らせるための目印です。

文字列リテラルには、コンパイラが末尾の\0を自動的に追加します。

"ABC"

通常は、次のように自分で\0を付ける必要はありません。

"ABC\0"

%% でパーセント記号を表示する

printfの書式文字列では、パーセント記号が書式指定の開始として使われます。

たとえば、%cや%sでは、先頭のパーセント記号によって書式指定が始まっています。

そのため、パーセント記号自体を表示するときは%%と記述します。

printf("達成率は80%%です\n");

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

達成率は80%です

ソースコードと表示結果の関係は、次のようになります。

ソースコード内の表記画面上の表示
%%%
50%%50%
100%%完了100%完了

%%は別の値を変換して表示するものではありません。そのため、対応する引数は必要ありません。

printf("進捗率は75%%です\n");

図2:%c・%s・%%の役割

この図から分かること

%cは1文字、%sは文字列を表示します。それぞれに対応する値をprintfの引数として渡します。

%%はパーセント記号を表示する特別な書き方です。ほかの値を変換するものではないため、追加の引数は必要ありません。

文字・文字列・パーセント記号を表示してみよう

%c、%s、%%を1つのプログラムで確認します。

信号記号と案内メッセージを表示するプログラム

ファイル名:5_5_1.c

#include <stdio.h>

int main(void)
{
    /* 3つの信号記号を1文字ずつ表示する */
    printf("信号記号: %c %c %c\n", 'R', 'Y', 'G');

    /* 2つの文字列を続けて表示する */
    printf("案内文  : %s%s\n", "安全を確認して", "進んでください");

    /* パーセント記号を表示する */
    printf("確認作業: 60%%完了\n");

    return 0;
}
実行結果の例
信号記号: R Y G
案内文  : 安全を確認して進んでください
確認作業: 60%完了

3つの%cと3つの文字が対応している

最初のprintfには、%cが3つあります。

printf("信号記号: %c %c %c\n", 'R', 'Y', 'G');

後ろに渡した3つの文字が、左から順番に対応します。

1つ目の%c ← R
2つ目の%c ← Y
3つ目の%c ← G

書式指定の数と、後ろに渡す値の数が一致しているのがポイントです。

%cの間には空白があるため、実行結果でもR、Y、Gの間に空白が入ります。

2つの%sで案内文を作っている

次のprintfには、%sが2つあります。

printf("案内文  : %s%s\n", "安全を確認して", "進んでください");

1つ目の%sには安全を確認して、2つ目の%sには進んでくださいが対応します。

書式文字列内の%sと%sの間には空白がありません。そのため、2つの文字列がつながって表示されます。

安全を確認して進んでください

%%でパーセント記号を1つ表示している

最後のprintfでは、%%を使用しています。

printf("確認作業: 60%%完了\n");

ソースコード上ではパーセント記号を2つ書いていますが、実行結果では1つになります。

ソースコード:60%%
実行結果  :60%

%%には対応する値がないため、このprintfでは書式文字列以外の引数を渡していません。

文字と文字列の違いを表で確認する

文字と文字列の違いをもう一度整理しておきましょう。

項目文字文字列
内容1文字0文字以上の文字の並び
囲み方シングルクォーテーションダブルクォーテーション
データの例A、B、#ABC、Hello、こんにちは
書式指定%c%s
終端の\0付かない末尾に付く
主な用途評価記号、区切り記号メッセージ、名前、案内文

C言語のコードでは、次の対応になります。

printf("%c\n", 'A');
printf("%s\n", "ABC");

%cと%sを混同しないようにする

文字には%c、文字列には%sを使用します。

正しい組み合わせは次のとおりです。

printf("%c\n", 'A');
printf("%s\n", "A");

次の組み合わせは正しくありません。

printf("%s\n", 'A');
printf("%c\n", "A");

1行目では、%sに1文字の値を渡しています。

2行目では、%cに文字列を渡しています。

書式指定とデータの種類が一致していないため、正しい動作は保証されません。表示が乱れたり、プログラムが異常終了したりする可能性があります。

迷ったときは、囲み方を確認すると分かりやすいでしょう。

  • シングルクォーテーションで囲んだ文字には%cを使う
  • ダブルクォーテーションで囲んだ文字列には%sを使う

パーセント記号を1つだけ書かない

次の書き方では、表示したいパーセント記号が1つだけ書かれています。

printf("達成率は75%です\n");

printfは、パーセント記号の後ろを変換指定として読み取ろうとします。しかし、ここには正しい変換指定子がありません。

パーセント記号を表示するときは、%%と書きます。

printf("達成率は75%%です\n");

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

達成率は75%です

書式指定と値の数をそろえる

次のprintfには%cが2つあり、対応する文字も2つあります。

printf("%c %c\n", 'A', 'B');

この対応は正しい形です。

1つ目の%c ← A
2つ目の%c ← B

次のコードでは、%cが2つあるのに文字が1つしかありません。

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

2つ目の%cに対応する値がないため、正しい動作は保証されません。

%sでも同じです。

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

%sが2つあるため、文字列も2つ必要です。

printf("%s %s\n", "Good", "Morning");

printfを使うときは、次の2点を確認しましょう。

  • 書式指定と値の数が一致しているか
  • 書式指定とデータの種類が一致しているか

図3:文字表示で確認する3つの基本ルール

この図から分かること

文字の表示では、データの種類に合わせて%cと%sを使い分ける必要があります。パーセント記号の表示には%%を使います。

さらに、書式指定の数と値の数をそろえることも大切です。この3つを確認すれば、printfによる文字表示の間違いを減らせます。

変換指定子の名前の由来

printfの変換指定子は、関連する英単語と結び付けると覚えやすくなります。

変換指定子関連する英語表示内容
ccharacter文字
sstring文字列
ddecimal符号付き10進整数
ooctal8進整数
xhexadecimal16進整数
ffloating point通常表記の浮動小数点数
eexponent指数表記の浮動小数点数

今回の中心になるcとsは、次の対応で覚えると分かりやすいでしょう。

c → character → 1文字
s → string    → 文字列

名前の由来を知っておくと、書式指定の役割を思い出しやすくなります。

文字・文字列・整数を組み合わせる

1つのprintfでは、異なる種類の書式指定を組み合わせることもできます。

char grade = 'B';
int score = 88;

printf("評価は%c、点数は%d点です\n", grade, score);

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

評価はB、点数は88点です

このprintfでは、左から次のように対応しています。

書式指定対応する変数表示する内容
%cgrade文字B
%dscore整数88

文字、文字列、数値を組み合わせることで、数値だけを表示するよりも意味が伝わりやすくなります。

評価結果を分かりやすく表示してみよう

これまでに学習した%c、%s、%d、%%を組み合わせて、評価結果を表示します。

評価記号とメッセージと達成率を表示するプログラム

ファイル名:5_5_2.c

#include <stdio.h>

int main(void)
{
    /* 評価記号と達成率を用意する */
    char grade = 'B';
    int achievement_rate = 88;

    /* 文字、文字列、整数、パーセント記号を表示する */
    printf("評価記号: %c\n", grade);
    printf("評価内容: %s\n", "もう少しで目標達成です");
    printf("達成率  : %d%%\n", achievement_rate);

    return 0;
}
実行結果の例
評価記号: B
評価内容: もう少しで目標達成です
達成率  : 88%

char型の変数を%cで表示している

評価記号は、char型のgradeに保存しています。

char grade = 'B';

gradeに保存されているのは1文字なので、表示には%cを使用します。

printf("評価記号: %c\n", grade);

実行すると、%cの位置にBが表示されます。

文字列を%sで表示している

評価内容は、文字列リテラルとしてprintfへ直接渡しています。

printf("評価内容: %s\n", "もう少しで目標達成です");

書式文字列の%sに、後ろの文字列が対応します。

このように、文字列リテラルは変数へ保存しなくても、printfの引数として直接渡せます。

%dと%%を組み合わせている

達成率を表示する行では、%dと%%を続けて使用しています。

printf("達成率  : %d%%\n", achievement_rate);

それぞれの役割は次のとおりです。

書式文字列の部分役割
%dachievement_rateの値88を表示する
%%パーセント記号を1つ表示する
\n表示後に改行する

%dにはachievement_rateが対応しますが、%%には対応する値がありません。

その結果、次のように表示されます。

達成率  : 88%

文字を添えると数値の意味が伝わりやすくなる

次の表示では、88が何を表しているのか分かりません。

printf("%d\n", 88);

88

説明文とパーセント記号を加えると、値の意味が分かりやすくなります。

printf("達成率は%d%%です\n", 88);

達成率は88%です

利用者に分かりやすい表示を作るときは、次の点を意識するとよいでしょう。

  • 値の前後に意味の分かる説明を付ける
  • 文字には%cを使う
  • 文字列には%sを使う
  • パーセント記号には%%を使う
  • 書式指定と値の順番をそろえる
  • 行の終わりに\nを入れる
  • 必要な場所に空白を入れる

%c、%s、%%を使えるようになると、案内メッセージ、メニュー、評価結果、進捗表示などを作れるようになります。文字やメッセージを変えながら実行し、書式指定と値がどのように対応するか確認してみてください。