C言語　printfのフォーマット指定子

# フォーマット指定子の構文

`prinf("%s\n","aiueo");`のように書いたときの`%~`の構文についてです。

以下の順に宣言されています。

```c
%[flags][width][.precision][length]type
%[フラグ][最小フィールド幅][.精度][長さ修飾子]変換指定子
```

## フラグ【 Flags field 】

フラグ | 意味
--- | ---
- | フィールドの左寄せ
+ | 常に符号を出力
空白 | 数値が正または 0 の場合は符号の代わりに空白を出力
# | 代替形式。基数を表すプレフィックスの出力等を指定
0 | 出力文字数が最小フィールド幅未満の場合は'0'を出力

### #について補足

Type | 効果
--- | ---
g, G | 後続のゼロが削除されない
f, F, e, E, g, G |  出力には常に小数点が含まれる。
o, x, X | 0, 0x, 0Xがゼロ以外の数値の前に出力される

```c
#include <stdio.h>

int main()
{
    printf("=== flag Field ===\n");

    printf("\n*** フラグなし ***\n");
    printf("-10\n => [%d]\n", -10);
    printf("10\n => [%d]\n", 10);

    printf("\n*** [+] プラマイの出力 ***\n");
    printf("-10\n => [%+d]\n", -10);
    printf("10\n => [%+d]\n", 10);

    printf("\n*** [ ] プラマイの代わりにスペースを出力 ***\n");
    printf("-10\n => [% d]\n", -10);
    printf("10\n => [% d]\n", 10);

    printf("\n*** [<number>] 最小フィールド未満の場合は0を出力 ***\n");
    printf("-10\n => [%05d]\n", -10);
    printf("10\n => [%05d]\n", 10);

    printf("\n*** [#] プレフィックスの指定 ***\n");
    printf("-10\n => [%#x]\n", -10);
    printf("10\n => [%#x]\n", 10);
    printf("10\n => [%x]\n", 10);
    printf("-1\n => [%#x]\n", -1);
    printf("1\n => [%#x]\n", 1);
    printf("1\n => [%x]\n", 1);

    printf("\n*** [-] フィールドの幅を左寄せにする ***\n");
	printf("10\n => [%-*d %s]\n",10,10, "aiueo");
	printf("11541\n => [%-*d %s]\n",10,11541, "aiueo");
    return (0);
}

```

```terminal
=== flag Field ===

*** フラグなし ***
-10
 => [-10]
10
 => [10]

*** [+] プラマイの出力 ***
-10
 => [-10]
10
 => [+10]

*** [ ] プラマイの代わりにスペースを出力 ***
-10
 => [-10]
10
 => [ 10]

*** [<number>] 最小フィールド未満の場合は0を出力 ***
-10
 => [-0010]
10
 => [00010]

*** [#] プレフィックスの指定 ***
-10
 => [0xfffffff6]
10
 => [0xa]
10
 => [a]
-1
 => [0xffffffff]
1
 => [0x1]
1
 => [1]

*** [-] フィールドの幅を左寄せにする ***
10
 => [10         aiueo]
11541
 => [11541      aiueo]
```

## 最小フィールド幅【 Width field 】

Widthフィールドは、出力する文字の最小数を指定し、通常、表形式の出力で固定幅のフィールドを埋めるために使用されます。それ以外の場合、フィールドは小さくなりますが、特大のフィールドは**切り捨てられません。**

`%*d`のようにアスタリスクで示します。引数の部分で長さを指定してあげます。

```c
#include <stdio.h>

int main()
{
	printf("\n=== width Field ===\n");

	printf("\n*** 10に指定 ***\n");
	printf("-10\n => [%*d]\n",10,-10);
	printf("10\n => [%*d]\n", 10,10);

	printf("\n*** 5に指定 ***\n");
	printf("123456\n => [%*d]\n", 5,123456);
	printf("-123456\n => [%*d]\n", 5,-123456);
	return (0);
}
```

```terminal
=== width Field ===

*** 10に指定 ***
-10
 => [       -10]
10
 => [        10]

*** 5に指定 ***
123456
 => [123456]
-123456
 => [-123456]
```

## .精度【 Precision field 】

[精度]フィールドは通常、特定のフォーマットタイプに応じて、出力の最大制限を指定します。
浮動小数点数値タイプの場合、出力を丸める小数点の右側の桁数を指定します。
文字列型の場合、出力する文字数を制限します。その後、文字列は切り捨てられます。

```c
#include <stdio.h>

int main()
{
	printf("\n=== precusion Field ===\n");

	printf("\n*** 4に指定 ***\n");
	printf("-10\n => [%.*d]\n",4,-10);
	printf("10\n => [%.*d]\n", 4,10);
	printf("aiueo\n => [%.*s]\n", 4, "aiueo");
	return (0);
}
```

```terminal
=== precusion Field ===

*** 4に指定 ***
-10
 => [-0010]
10
 => [0010]
aiueo
 => [aiue]
 ```

## 長さ指定子【 Length field 】

整数変換(d/i/o/u/x/X)時、その引数の長さを指定する。

長さというので、特殊な役割があるのかと思いましたが、表現したい型を1対1対応で決まっています。
プログラム上では整数と一言に言っても、様々な種類があり、それを表現するための修飾子です。

自分は変換指定子とごっちゃになっていました。

修飾子 | 意味
--- | ---
hh | 実引数は char 型
h | 実引数は short 型
l（エル） | 実引数は long 型または wchar_t 型または double 型[3]
ll（エルエル） | 実引数は long long 型
j | 実引数は intmax_t 型
z | 実引数は size_t 型
t | 実引数は ptrdiff_t 型
L | 実引数は long double 型

### 使用例

型             | 10進数 | 16進数 | 8進数 | 補足 
---            | ---   | ----  | --- | ---
signed char    | %hhd |        |     |  文字、C99以降
unsigned char  | %hhu | %hhx | %hho | 文字、C99以降
short          | %hd |   |   |  
unsigned short | %hu | %hx | %ho |  
int            | %d |   |   |  
unsigned int   | %u | %x | %o |  
long           | %ld |   |   |  
unsigned long  | %lu | %lx | %lo |  
wint_t         | %lc | | |  文字、C99以降
wchar_t        | %lc | | |  文字、C99以降
long long      | %lld |   |   | C99以降
unsigned long long | %llu | %llx | %llo | C99以降

型            | 書式 | 補足
--- | --- | --- 
float         | %f |  実数型
double        | %f |   実数型
long double   | %Lf |   実数型、C99以降

型         | 10進数 | 16進数 | 8進数 | 補足
---       | --- | --- | --- | ---
intmax_t  | %jd |   |   | C99以降
uintmax_t | %ju |   |   | C99以降
ssize_t   | %zd |   |   | C99以降
size_t    | %zu |   |   | C99以降
ptrdiff_t | %td | %tx | %to	| C99以降

## 変換指定子

これは見慣れているやつです。

変換指定子 | 意味
--- | ---
d, i | int 型の引数を 10 進符号付き整数に変換する
u | unsigned int 型の引数を 10 進符号無し整数に変換する
o | unsigned int 型の引数を 8 進符号無し整数に変換する
x, X | unsigned int 型の引数を 16 進符号無し整数に変換する
f, F | double 型の引数を小数形式浮動小数点数に変換する
e, E | double 型の引数を指数形式浮動小数点数に変換する
g, G | f か e のどちらかに変換する (変換の結果として得られる指数が -4 より小さいか，精度以上の場合は e 形式になる)
a, A | double 型の引数を 16 進浮動小数点に変換する
c | int 型の引数を 一端 unsigned char 型に変換し，変換結果の文字を書き込む
s | 文字配列の先頭要素へのポインタを文字列に変換する
p | void 型へのポインタを処理系定義の方法で表示文字の並びに変換する
n | 整数変数に出力済み文字数を格納する (引数は符号付き整数型へのポインタ)
% | '%' を出力する

## 参考

[C言語関数辞典 - printf](http://www.c-tipsref.com/reference/stdio/printf.html)

[出力書式のまとめ 変換指定子 - printf出力書式まとめ - 碧色工房](https://www.mm2d.net/main/prog/c/printf_format-01.html)

[printf ‐ 通信用語の基礎知識](https://www.wdic.org/w/TECH/printf)

[printf format string - Wikipedia](https://en.wikipedia.org/wiki/Printf_format_string)