sironekotoroの日記

Perl で楽をしたい

printfと私

コロナウイルス禍の昨今

Perl入学式はもとより、Perl のお祭り YAPC::Kyoto 2020 や他の技術系カンファレンスも延期になってしまい、なんとも寂しい限りです。

特にYAPC::Kyoto 2020 は前々日から京都入りして、鞍馬寺比叡山、福知山など、ちょっと遠いところに行こうと思っていたので、本当に残念です。

で、そんな状況とはあんまり関係なく、printfの話をしたいと思います。

printf , sprintf

Perl入学式では取り上げていないprintfなんですが、とても便利な関数です。Perlの組み込み関数なので、モジュールのインポートなどは不要です。

perldoc.jp

通常のprintは引数にとったものをそのまま表示するだけです。

print "hogehoge\n"; # hogehoge

print "hogehoge", "fugafuga", "piyopiyo", "\n"; # hogehogefugafugapiyopiyo

このprintの末尾にfを加えたprintfでは引数を2個以上取ることになります。

printf("%s\n", "hogehoge"); # hogehoge

printも、printfも同じく、 hogehoge と表示して改行するだけのコードです。

printf の最初の引数 "%s\n" は文字列を代入して改行、という意味になります。第二引数である文字列が%sのところに入る訳ですね。

文字列ではなくて、数字も代入できます。第一引数の違いに注目です。

printf("%d\n", 5.30);   # 5

printf("%f\n", 5.30);   # 5.300000

第二引数は双方共5.30 で同じものですが、表示結果は異なります。

"%d\n"の場合には整数、"%f\n"の場合には小数点第6位まで表示されています。

このように、引数に書式を適用して(フォーマットして)出力できるのがこのprintfなのです。

小数点の桁数は、以下のように調節が可能です。

printf("%.2f\n", 5.30);   # 5.30

整数の方も、0埋めが可能です。

printf("%02d\n", 5);   # 05

例えば、日付なんかで2020-03-28 と表示したいときなんかに0埋めができることを知っていると楽です。

printf("%04d-%02d-%02d\n", 2020, 3, 20);   # 2020-03-20

sprintf はフォーマットした文字列や数字を変数に格納するときに使います。引数などはprintfと同じです。

my $date = sprintf("%04d-%02d-%02d\n", 2020, 3, 20);
print $date;    # 2020-03-20

この記事を書こうと思ったきっかけ

かつてのうちは「printf、なんか引数多いし、%sとか%dとかよくわからんし、printでいいよね」と思い綺麗に忘れ去ったのでした。

その結果、このようなサブルーチンが自分のコードのそこかしこから発掘されたのです。

sub add_zero {
    my $num = shift;
    if (length $num == 1){
        $num = 0 . $num;
    }
    return $num;
}

print add_zero(1) . "\n";   # 01
print add_zero(12) . "\n";  # 12

これは、引数にとった数字が1桁だったら0を左側に1つつける(0埋めする)、というサブルーチンです。

しかし、数字と文字のチェックをしていないため、

print add_zero('a') . "\n";  # 0a

という結果が返ってきます。

printfであれば、第一引数が数字%dであるのに文字が入っていると警告が出ます。

printfを知っていれば、このサブルーチン書かなくてもよかったのになー、という思いも込めて(あとしばらくブログ書いてなかったなーという反省もあり)このエントリを書いたのでした。