2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

これは何?

書式指定文字列に変なこと書いてもエラーにならない事に気づいて、色々試してみた記録

各種言語の対応

go

この現象を発見したのは go。

go
fmt.Printf("%d %+d %++d %+++d %++++d\n", 1, 1, 1, 1, 1)
//=> 1 +1 +1 +1 +1

二個以上書いても意味ないけど、エラーにならない。

+ を書ける場所には も書けるが、意味的に共存できない。

戦わせると

go
fmt.Printf("[%+d]\n", 1) // [+1]
fmt.Printf("[% d]\n", 1) // [ 1]
fmt.Printf("[%+ +d]\n", 1) // [+1]
fmt.Printf("[% + d]\n", 1) // [+1]

+ が勝つ。

後勝ちだろうと予想していたので、予想が外れた。

ruby

ruby も同様に "%++++++++++++d" % 1 などはエラーにならない。

戦わせてみると

ruby
"[+]%+d [ ]% d [+ +]%+ +d [ + ]% + d" % [1,1,1,1]
#=> "[+]+1 [ ] 1 [+ +]+1 [ + ]+1"

go と同じく + が強い。

python3

python3 も同様に "%++++++++++++d" % 1 などはエラーにならない。

戦わせてみると

python3
"[+]%+d [ ]% d [+ +]%+ +d [ + ]% + d" % (1,1,1,1)
#=> '[+]+1 [ ] 1 [+ +]+1 [ + ]+1'

こちらも + が強い。

perl

perl
printf("[+]%+d [ ]% d [+ +]%+ +d [ + ]% + d", 1,1,1,1);'
#=> [+]+1 [ ] 1 [+ +]+1 [ + ]+1

こちらも + が強い。

こんなバグっぽい挙動でみんなの意見が揃うのが気持ち悪い。

PHP

PHP は perl と同じ結果になりやすいという印象がある。

PHP8.2.19
<?php
printf("[+]%+d [ ]% d [+ +]%+ +d [ + ]% + d", 1,1,1,1);
#=> [+]+1 [ ]1 [+ +]+1 [ + ]+1

やはり perl と同じで、つまり + が強い。

C++

コンパイラによっては警告を出してくれた。

c++(clang18.1.0)
printf("[+]%+d [ ]% d [+ +]%+ +d [ + ]% + d", 1,1,1,1);
//=> warning: flag ' ' is ignored when flag '+' is present [-Wformat]

'+' があるんで ' ' は無視するよ、という警告で、'+' が二個あるよ、という警告ではない。

実際、 %++d% d などでは警告は出なかった。

clang と gcc と MSVC を試したけど、みんな go と同じく + が強く、- が弱い。

ここまで揃っていると仕様があるのかなと思ったりするけど調べてない。

Java

Java はエラーにしそうだなと予想していた。

Java
 System.out.printf("%++d", 1);
 //=> Exception in thread "main" java.util.DuplicateFormatFlagsException: Flags = '+'

やはりエラー。そういう人だよね。

wsprintf (Windows)

MSDN には「もう使わないで」と書いてあるけど wsprintf は今でも使える。
この関数は

  • 書き込まれるバッファは 1024 バイト固定
  • %f がない

などの特徴がある気持ち悪い関数で、こいつなら他と違う挙動になるかと思ったんだけど、そもそも + などのフラグがなかった。残念。

%##########x%000000000d のような無駄な指定がエラーにならないのは go などと同様だったんだけど、 + のような戦いはできないのであった。

まとめ

C 言語に由来すると思われる
 "%d"
のような書式文字列に
 "++++++++++%d"
のようなことを書いても意味がないわけだけど、 Java 以外はエラーにしない。

それと、この + を戦わせると、みんな + の勝ちだった。不思議。
普通に書いたら後勝ちになりそうなものだと想像していたんだけれど。

思いつく限りの言語で試したんだけど、他に C の printf と同じような書式文字列が使える 言語 / ライブラリ ってなんかあったっけ。

2
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?