第2章06 いろんな書式指定子@イチからゲーム作りで覚えるC言語

鍵屋でかいもの

イチからゲーム作りで覚えるC言語
連載ページ一覧へ
2章07 変数に配列を使う
NEXT : 2章07 変数に配列を使う
2章05 文字列変数の宣言、初期化と表示 : PREV

この記事でやること

前回はプロジェクト「0040_mojiretsu」を新しく作り、文字列変数を使って文字を表示するプログラムを作成しました。いままでにprintf関数で表示するときに %d、%f、%s とか、いくつかの変換指定子(Conversion specifiers)を説明してきました。
今回は、いままで説明したものを含む、よく使ういくつかの変換指定子をお話し、便利な表示方法を作ってみましょう。

この記事はゆる~くC言語でコンソールゲームを作りながらプログラミングを学ぶための連載記事です。シリーズものですので記事の一覧はこちらを参照してくださいね。

いくつかの変換指定子を使用したプログラム

ではでは 文字列を取り扱うサンプルプログラムを作成してみましょう。
プロジェクト「0050_stringformatid」を新しく用意し、プロジェクトに空の「Conversion.c」を追加し、下のソースコードをコピペして動かしてみましょう。

#include <stdio.h>
int main() {
 char keytype = 'b';
 char *player = "ぷらんく";
 char *theif = "盗賊";
 short level = 5;
 float breakkeyPerc = 3.2F;
 double biorhythm = 5.123L;

 printf("%s:タイプ %c の鍵って売ってますか?\n", player, keytype);
 printf("%s:売ってない。ロックピックならあるぜ\n", theif ));
 printf("%s:わたしの開錠スキルどれくらいだったっけ\n\n", player);
 printf("+------[ステータス]------+\n");
 printf("|%10s : %-11s|\n", "名前" , player );
 printf("|%10s : %03d |\n", "レベル" , level );
 printf("|%10s : %8.1f %% |\n", "開錠確率" , breakkeyPerc);
 printf("|%10s : %+8.3lf %% |\n", "体調", biorhythm);
 printf("+------------------------+\n");
}

コピペなりして、実行してみて下さい。下の結果になると思います。

ぷらんく:タイプ b の鍵って売ってますか?
盗賊:売ってない。ロックピックならあるぜ
ぷらんく:わたしの開錠スキルどれくらいだったっけ

+------[ステータス]------+
|      名前 : ぷらんく   |
|    レベル : 005        |
|  開錠確率 :      3.2 % |
|      体調 :   +5.123 % |
+------------------------+

3~8行目はここまでこのシリーズで何度かお話した、変数の初期化を行っています。いままでの復習も含めて、いろいろと変数も入れています。
9行目までプログラムが実行された時点で、変数はこんな状態になっています。

  • 変数「keytype」には数値「66」が入っており、文字では「b」に相当する。
  • 変数「player」には文字列「ぷらんく」 が入っている。
  • 変数「theif」には文字列「盗賊」が入っている。
  • 変数「level」には整数 5 が入っている。
  • 変数「breakkeyPerc」には float 型の小数 3.2 が入っている。
  • 変数「biorhythm」には double 型の小数 5.123 が入っている。

今回は 10 行目以降の、文字を表示するところを書いていきます。
といっても10行目、11行目はこのシリーズの前記事でもお話した、「%s」「%c」という整数を表示する変換指定子(Conversion specification)を使っています。「%s」が文字列の表示、「%c」は一文字を表示となります。
よく使用する変換指定子をまとめます。

よく使われる変換指定子

int 型とか char 型とかそれぞれの型にあわせて変換指定子を使い分ける必要があるので気を付けでくださいね。今後よく使いそうな指定子と使用例を書いておきます。べつに暗記する必要はないので、必要なときに検索したり振り返れば良いかと思います。
ここに記載のない変わった指定子もあるので、また今度、別の機会に一覧と使い方をまとめたいと思います。

よく使われる書式指定子と使い方の例
処理 記号
1文字表示 %c char input = ‘A’;
printf(“A と B、選ばれたのは %c のお茶でした”, input);
文字列を表示 %s char* message = “ここははじまりの村ですか?”;
printf(“ぷらんく:%s“, message);
整数を表示 %d short life = 3;
printf(“のこりライフは %d です。“, life);
long型の整数を表示 %ld long exp = 123456789L;
printf(“次のレベルまで経験値が %ld 必要。”, exp);
float型の浮動小数点数を表示 %f float taion = 35.0f;
printf(“体温は %f です。低体温症のステータス。”, taion);
double型の浮動小数点数を表示 %lf double kyori = 149597870.0 * 1000.0;
printf(“太陽までの距離は %lf メートル”, kyori);
※ 指定子の部分は「149597870000.000000」で表示
浮動小数点数を指数形式で表示 %e double kyori = 149597870.0 * 1000.0;
printf(“太陽までの距離は %e メートル”, kyori)
※ 指定子の部分は「1.495979e+11」で表示

表示するときに桁数、右詰、左詰めを指定

14行目について、見ていきましょう。ここでは2つの文字列を表示しています。

 printf("|%10s : %-11s|\n", "名前" , player );

printf関数の一つ目の引数の中で書いている、「%10s」ですが、「10文字の幅を確保して、右詰めで文字を表示する」という意味になります。書き方は「%文字幅s」です。「%s」にプラスして、「表示する文字幅」と「右詰め」を指定しています。
ここでは文字列「名前」を「%10s」に従って表示しています。

そして、次の「%-11s」ですが、「11文字の幅に左詰めで文字を表示する」という意味になります。書き方は「%文字幅s」です。「%」の隣に「-」マイナス記号がありますが、これを書くことで「左詰め」という意味になります。
ここでは変数 player の中身を「%-11s」に従って表示しています。

表示するときの数字を0埋め指定

15行目について、見ていきましょう。ここでは整数であるレベルを 3 桁で表示しています。

 printf("|%10s : %03d |\n", "レベル" , level );

最初の「%10s」は先ほどお話しました。次の「%03d」ですが、「3文字ぶんの幅を使って数字を表示する。空いた部分は 0 で埋めて表示する」という意味になります。「%d」にプラスして、「文字幅」と、「0埋め」を指定しています。

小数点以下の表示桁数を指定

16行目について、見ていきましょう。

 printf("|%10s : %8.1f %% |\n", "開錠確率" , breakkeyPerc);

ここではfloat や double などの浮動小数点数を表示する形式を整える指定をしています。
小数は「%全体の文字幅 . 小数点以下の表示桁」という形式で指定できます。
ですので、例えば「%8.1f」だと、「float 型を 全体 8 文字幅、小数以下を 1 桁、右詰めで表示する」。という意味になります。小数点「.」も 1 文字に含みます。

例には書いていませんが、「%.3f」と書くと、「float型を小数以下を3桁まで表示する」指定ができます。

数値の表示でプラス・マイナスの以下の表示桁数を指定

17行目について、見ていきましょう。

 printf("|%10s : %+8.3lf %% |\n", "体調", biorhythm);

ここでは「%+8.3lf」という書き方が登場します。ここの+記号は「数値が 0 以上ならプラス記号をつけて表示する」という意味になります。
ですので、この+記号をつけると、かならずプラス・マイナスの記号が数値の前につきます。
また、その後の「%%」は単純に一つの「%」を表示する、という意味になります。

よく使われる表示の桁や右詰・左詰めなどのまとめ

よく使われる桁や右詰め・左詰めなどの使用例をまとめておきます。

よく使われる表示整形のための指定子と使い方の例
結果
printf(“%7s” , “Okome”); 7文字幅で右詰めで表示します。

O k o m e
printf(“%-7s” , “Tabeyo”); 7文字幅で左詰めで表示します。

 T a b e y o
printf(“%06d” , 5000); 6文字幅 0埋め で表示します。

 0 0 5 0 0 0
printf(“%+5d” , 123); 5文字幅 プラス記号付き、右詰で表示します。

+ 1 2 3
printf(“%6.3f” , 9.876543f ); 全体6文字幅、小数点以下 3 桁で右詰めで表示します。

9 . 8 7 7

※表示されない4桁目が「5」で四捨五入され、3桁目が「6」から「7」になっています。

printf(“%+6.1f” , 12.34f ); 全体6文字幅、小数点以下 1 桁で右詰めで表示します。

+ 1 2 . 3
printf(“%-+6.1f” , 56.78f ); 全体6文字幅、小数点以下 1 桁で左詰めで表示します。

+ 5 6 . 7
printf(“%2s” , “Afureta”); 全体2文字幅で文字を表示しようとしますが、文字はもっと長いので溢れます。

A f u r e t a

※こんな感じで、文字幅を超えないと表示できないときは、文字幅を指定しても、幅を超えて表示されます。つまり、文字幅を指定すると「最低限表示に使われる文字幅」を指定したということになります。

おまけの細かなお話

このページでまとめた指定子について、自分なりに調べた内容をメモしています。
詳しいお話や間違ってるよ!というご指摘があればこっそりコメントなどで教えてもらえると嬉しいです。

そもそも指定子ってなんだろ?って気になる方。ここでは指定子とはあらかじめ仕様で決められた、他と区別するための文字記号の組み合わせ、くらいの認識で良いかと思います。
ここからは細かい話と自分なりのメモですが、手元にあるC言語仕様書的な本「THE C PROGRAMMING LANGUAGE 初版」(K&R著)では%c とか %f とかのことを identifier とか specifier ではなく、”% sign”(%の記号)とか “The conversion specification” (直訳:変換のための記述)って書いてますね。2018年5月時点で最新のC11規格N1570でも同じ表現でした。
厳密にはそもそも printf 関数の指定子である %s とか %f とかの仕様はそもそもC言語として決めた仕組みじゃないらしいです。C言語が利用している当時のUNIX標準ライブラリ側の仕様を使ってるよ!ってかいてありました。(K&R本)
VisualStudio のC言語コンパイラ処理系でも printf 関数は OS が標準的に利用する DLL (Dynamic Linker Library:標準的な機能をまとめた必要に応じて呼び出すことのできるライブラリ)の機能を呼び出して使っているようです。
英語のC言語関連、標準ライブラリ関連の資料を読んでると、Conversion Specification(日本語で変換指定子)は、 Format Specifiers(日本語で書式指定子、フォーマット指定子)のうち、printf関数等でデータを文字に変換する「%d」や「%f」という指定子のみを限定して指しているという意味と思っています。(が、自信がないので詳しい方いましたら教えていただけると嬉しいです。)

あとがき

今回はここまで。お疲れさまでした。
イチからゲーム作りで覚えるC言語
連載ページ一覧へ
2章07 変数に配列を使う
NEXT : 2章07 変数に配列を使う
2章05 文字列変数の宣言、初期化と表示 : PREV

非常に参考になったサイトさまや、参考文献など

ページの更新履歴

更新日 更新内容
更新なし