C言語⑤(2025/05/28)

printf()の書式指定

●基本的な書式指定子

出力変換指定子説明
%d整数(10進数)printf("%d", 42);
%i整数(10進数)printf("%i", 42);
%o整数(8進数)printf("%o", 42);
%x / %X整数(16進数, 小文字/大文字)printf("%x", 42);
%f浮動小数点(小数)printf("%f", 3.14);
%e / %E指数表記(小文字/大文字)printf("%e", 3.14);
%g / %G短縮浮動小数点(%f or %e のどちらか最適な方)printf("%g", 3.14);
%c単一文字printf("%c", 'A');
%s文字列printf("%s", "Hello");
%pポインタのアドレスprintf("%p", &x);

●フォーマットの修飾

  1. 幅指定 (%10d) – 数字の桁数を指定
  2. 精度指定 (%.2f) – 小数点以下の桁数を指定
  3. 左寄せ (%-10s) – 指定幅で左寄せ
  4. ゼロ埋め (%05d) – 空白の代わりにゼロを埋める

※ゼロパディングとゼロサプレス

- ゼロ埋め(Zero Padding): 指定した桁数になるまで、数値の左側にゼロを追加すること。例えば 42 を5桁にゼロ埋めすると 00042 になります。
- ゼロサプレス(Zero Suppress): 逆に、数値の先頭にある不要なゼロを削除すること。例えば 00042 をゼロサプレスすると 42 になります。
つまり、printf("%05d", 42); のようなゼロ埋めは「ゼロパディング」と呼ばれ、「ゼロサプレス」とは異なる処理です。
参考:https://wa3.i-3-i.info/diff352zero.html
(by Copilot)

上記を踏まえて
【今日のコード①】

#include<stdio.h>

int main(void)
{
	int age1 = 45, age2 = 18, age3 = 46;
	int skin = 2;
	
	printf(" %d歳!でも%sは%d歳!!\n", age1,"心", age2);

	float weight = 82.6,weight2=75.6666,cash = 10000000.4466;
	printf("そして体重は%fkg!!\n", weight);

	skin = 0.2f;
	printf("面の皮の厚さは%fcm!!\n ",skin);

	printf("結婚は%04d歳までに!…学生婚!?\n", age3);

	printf("体重はそれまでに%6.2fkgまで落として見せる!\n", weight2);
	printf("資産は%12.2f円まで増やしたい!!!\n", cash);

	return 0;
}

実行結果

 45歳!でも心は18歳!!
そして体重は82.599998kg!!
面の皮の厚さは0.000000cm!!
 結婚は0046歳までに!…学生婚!?
体重はそれまでに 75.67kgまで落として見せる!
資産は 10000000.00円まで増やしたい!!!

・・・資産の小数点以下が反映されていないが、これは丸め誤差によるもの。

- 変数の型 (float) による影響
- float 型は 単精度 の浮動小数点数を扱いますが、これは約7桁程度の精度しかありません。
- 10000000.4466 のような大きい値は、単精度では正しく保持できないことがあり、丸め誤差が生じます。
- double 型を使用することで、より精度の高い値を保持できる可能性があります。
(by Copilot)

double cash = 10000000.4466 に修正すると下記の結果。

 45歳!でも心は18歳!!
そして体重は82.599998kg!!
面の皮の厚さは0.000000cm!!
 結婚は0046歳までに!…学生婚!?
体重はそれまでに 75.67kgまで落として見せる!
資産は 10000000.45円まで増やしたい!!!

うまく表示された。なお、表示桁数があふれた場合にはあふれた桁分は四捨五入される模様。

エスケープシーケンス
https://www.45game.tech/?p=193

例:文字配列arrayの最後にNULL文字を入れる

char array[5]
array[4] = '\0';

なお、\r\n:(CRLF)は16進数で0A0Dになるので、CRLFに変わって0A0Dと呼ばれる場合がある。

※NULL文字が自動で入る場合、入らない場合

C言語で文字列を扱う場合、最後の '\0' (ヌル文字) は自動で追加されます。
自動的に '\0' が追加されるケース
- 文字列リテラルの場合
char str[] = "Hello";
- → "Hello" の場合、メモリには [ 'H', 'e', 'l', 'l', 'o', '\0' ] のように 自動的に '\0' が最後に入る ので、文字列として正しく認識されます。
- strcpy() を使ったコピー
char str[10];
strcpy(str, "Test");
- → strcpy() 関数は 最後に '\0' を追加する ため、str は [ 'T', 'e', 's', 't', '\0', … ] のようになります。
'\0' を 手動で追加が必要なケース
- 手動で文字を配列に代入する場合
char str[6] = { 'H', 'e', 'l', 'l', 'o' }; // 最後の `'\0'` がない!
- → printf("%s", str); を使うと 意図しない結果 になる可能性があります(メモリのゴミデータが表示されることも)。
- → 解決策:
char str[6] = { 'H', 'e', 'l', 'l', 'o', '\0' };
- バッファサイズが足りない場合
char str[4] = "Test"; // `'\0'` を入れる余裕がない!
- → こうすると メモリの境界を超えてしまう 可能性があります。
まとめ✅ 文字列リテラル ("Hello") を使えば '\0' は自動で追加される
❌ 手動で文字を配列に入れる場合は '\0' を意識して追加する必要があるこのポイントを押さえれば、安心して文字列を扱えますね!😃
(by Copilot)

コメント

タイトルとURLをコピーしました