めのん@ひとりプログラミング同好会

このブログはすべてフィクションであり、実在の人物、団体とは一切関係ありません

PHPとCのprintf関数

こんばんは、PHPの猛勉強を始めためのんです!

プログラミング言語を勉強するにあたって、途中結果を画面に出力する関数を習得することは大事だと思います。 途中結果を確認できれば、気軽にいろいろ試してみることができますから。

マイコンなんかのプログラムだとそれができなくて、LEDの点灯状態を頼りにデバッグなんてこともあります。 UARTで文字列を出力できれば、もうこっちのもん! って感じです。

PHPでも標準出力に書き込みができれば便利だということで、どんな方法があるか調べてみました。

  • echo
  • fputs
  • printf

のような方法があるようです。 echo以外はCでもおなじみの関数ですが、関数名は同じでも微妙に仕様が異なるんですよ。

たとえばfputs関数ですが、Cの場合は次のような仮引数を受け取ります。

int fputs(const char *s, FILE *stream);

ところが、PHPのfputs関数は次のようになります。

fwrite ( resource $handle , string $string [, int $length ] ) : int

引数の順序が全然違います!

オプションの$lengthを無視すれば、仮引数の順序が逆になります。 これは罠ですよねー

そしていよいよprintf関数です。 ごく簡単な使い方をするだけならCとPHPのprintf関数は同じように使うことができます。 ところが、ちょっと凝った使い方をしようとすると非互換性に悩まされることになります。

PHPのprintf関数に%pや%nがないことはまあ許容範囲です。 %bが追加されていることも問題ありません。 C99から追加された%aや%Aがないのもまあいいでしょう。 %iがないのも許します。

でも、どうして#フラグがないのでしょうか? Cのprintf関数では、#フラグを付けることで、16進数や8進数なら0xなどの接頭辞が付きますし、浮動小数点数なら小数点が付きます。 結構大事な役割を果たしていると思うんですよ。

hやlなどの長さ修飾子が無いのもまあいいでしょう。

でも、最小フィールド幅や精度の振る舞いが全然違うのは納得がいきません。

たとえば、Cでは、

printf("[%010.5d]\n", 5);

とすれば、

[ 00005]

と出力されるんですよ。 ところがPHPだと、

[0000000005]

のようになります。

printf("[%0.5d]\n", 5);

だと、Cでは、

[00005]

ですが、PHPでは、

[5]

になってしまいます。

あらかじめPHPのprintf関数の癖を十分把握しておかないと、printfデバッグができなくなってしまいます。

PHPとCは同じ名前の関数が多いので、こういった問題が結構起きそうに感じました。 これからも、CプログラマーPHPを使ったときにはまりそうな罠を紹介していけたらと考えていますので、どうぞご期待ください。

それでは!!