LoginSignup
5
4

More than 5 years have passed since last update.

[C言語] あなたは正しいフォーマット文字列を使っていますか?

Last updated at Posted at 2016-12-01

katokenです。
本記事はACCESS Advent Calendar 2016の2日目の記事です。

あらまし

株式会社ACCESSでは、組み込み機器への自社製品のポーティングを多く手がけており、その多くはCやC++で書かれています。

昨日の記事で書いたとおり、開発中のログは基本的にfprintf()を用いてコンソール等へ流します。

fprintf()はフォーマット文字列を見てスタックから何バイトとってどのように文字列に変換するか決めるため、
フォーマット文字列と変数の型がマッチしていないと間違った値が表示されるどころかクラッシュすることもあります。

Question

さて、ここで問題です。

unsigned int, void*, size_t, uint64_t の型の変数の値をfprintf()を用いてコンソールに出力したい場合、
フォーマット文字列は何を使うべきでしょうか?

Answer

答えは、以下のとおりです。

  • unsigned int ... %u, %x
  • void * ... %p
  • size_t ... %zu
  • uint64_t ... PRIu64 マクロ (※ fprintf(stderr, "%" PRIu64 "\n", (uint64_t)64); のように使う)

みなさん安易にunsigned型に%d や、void*型に%lxuint64_t型に%lluとか使っていないでしょうか?
符号が変わったり、プラットフォームのポインタサイズが変わった時にきちんと表示してくれなくなったり、クラッシュするかもしれませんよ?

終わりに

かなり短かったですが、よく使う型とそれに対応するフォーマット文字列をクイズっぽく紹介しました。
昨日の記事uint64_tのタイムスタンプを出力する場合などは
プラットフォーム次第で%llu だったり%luだったりするので注意です。

(Goの記事書きたかったんだけど業務都合で間に合わなかったん...)

3日目の明日は @ikeyasu さんです。お楽しみに!

参考文献

5
4
2

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
5
4