C言語のフォーマット系関数(printf, sprintf/snprintf)でゼロ埋めや空白による左詰め/右詰めを実現する方法を紹介します。
C言語ではprintf関数やsprintf/snprintf関数の書式文字列に0
, -
フラグやフィールド幅を指定することで、ゼロ埋めや左詰め/右詰め処理を実現することができます。
printf("%4d", 12); // " 12"(右詰め)
printf("%-4d", 12); // "12 "(左詰め)
printf("%04d", 12); // "0012"(ゼロ埋め)
0
フラグでゼロ埋め、-
フラグで左詰めを指示します。フラグが指定されなかった場合には、指定されたフィールド幅で右詰めが行われます。細かな仕様や使い方については次項を参考にしてください。
目次
- フィールド幅の動的指定
- フィールド幅の注意点(符号、小数点)
- 文字列に対するゼロ埋め
- ゼロ埋め文字を右詰め/左詰めする方法
- ゼロ埋めと左詰めのフラグは同時に利用できない
- 『ゼロ埋め・右詰め・左詰め』の読み方について
右詰め
各変換指定子に対応する%
記号の末尾にフィールド幅を指定することで、数字を右寄せの状態で出力することができます。
printf("%4d", 12); // " 12"
printf("%2d", 1234); // "1234"(数値の桁数が優先される)
printf("%4d", -12); // " -12"(符号も含まれる)
printf("%9f", 3.14); // " 3.140000"(符号や小数点も含まれる)
左詰め
フィールド幅の前方に-
フラグを指定することで、数字を左寄せの状態で出力することができます。
printf("%-4d", 12); // "12 "
printf("%-4d", -12); // "-12 "
printf("%-+4d", 12); // "+12 "
printf("%-9f", 3.14); // "3.140000 "
ゼロ埋め
フィールド幅の前方に0
フラグを指定することで、数字をゼロ詰めの状態で出力することができます。
printf("%04d", 12); // 0012
printf("%08d", 12); // 00000012
printf("%09f", 3.14); // 03.140000
フィールド幅の動的指定
最小フィールド幅の値を動的に指定したい場合には、幅にアスタリスク(*
)を用いて対応する文字幅を引数で指定するようにします。指定された値はint型の実引数として解釈されます。
printf("%*s", 4, "12"); // " 12"
printf("%0*d", 4, 12); // "0012"
フィールド幅の注意点(符号、小数点)
フィールド幅はあくまで最小の表示幅であるため、表示対象の数値の桁数のほうが大きい場合には、そちらの幅が優先されます。
printf("%2d", 1234); // "1234"(数値の桁数が優先される)
printf("%4d", -12); // " -12"(符号も含まれる)
printf("%9f", 3.14); // " 3.140000"(符号や小数点も含まれる)
printf("%7.2f", 3.14); // " 3.14"(小数部の桁数は明示的に指定する)
なお、符号もフィールド幅に含まれます。また浮動小数点数型の出力時には小数点や少数部の桁数もフィールド幅に含まれます。
参考:小数点以下の桁数を指定する方法
文字列に対するゼロ埋め
文字列用の変換指定子%s
に0
フラグを指定してしまった場合には、未定義動作で警告が発生します。
// 未定義動作: Flag '0' results in undefined behavior with 's' conversion specifier
printf("%08s", "12"); // 00000012 (in /usr/bin/clang)
printf("%08s", "12"); // 0012 (with UTF-8)
この問題に対処するためには、一度数字に変換してからフォーマットを行うようにします。
printf("%08d", atoi("12")); // 00000012
ゼロ埋め文字を右詰め/左詰めする方法
ゼロ埋め後の文字列を右詰め/左詰め表示する方法が考えられます。
char num[5];
snprintf(num, 5, "%04d", 12); // num == "0012"
printf("%8s", num); // " 0012"
printf("%-8s", num); // "0012 "
ゼロ埋めと左詰めのフラグは同時に利用できない
ゼロ埋めと左詰めを一緒に行うことはできません。この場合は0
フラグが無視され、-
フラグによる右詰めが優先されます。
// 警告: Flag '0' is ignored when flag '-' is present
printf("%-04d", 12); // "12 " (not "1200")
ゼロ埋めされた文字列を左詰めしたい場合には前項の方法を参考にしてください。
『ゼロ埋め・右詰め・左詰め』の読み方について
ゼロ埋めという表現はゼロパティング(zero padding)と呼ばれることもあります。右詰め(right-padding)と左詰め(left-padding)はrpadやlpadと略されることがあり、口頭ではライトパディング(ライトパッド)やレフトパディング(レフトパッド)と呼ばれることもあります。なお日本のシステムエンジニアはSQL経験との関係からアールパッドやエルパッドと表現する人も多いように思います。また、人によっては右詰めのことを右寄せ・右揃え(right-justify)、左詰めを左寄せ・左揃え(left-justify)と言う人もいたりするので覚えておくと良いでしょう。