printf コード例

printf

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2024/07/06 14:45 UTC 版)

コード例

#include <stdio.h>

int main(void)
{
    int a = 1234;
    printf("%d %o %x\n", a, a, a);
    printf("%s %c\n", "abc", 'x');
    return 0;
}

上記のコードをコンパイルし実行すると、次の出力が得られる。

1234 2322 4d2
abc x

脆弱性

一般に、書式文字列を外部や利用者から自由に指定できる状態とすることはセキュリティホールの温床となるため望ましくない。特に%n書式を用いたものが有名である[8]。Visual C++のCRTでは既定で%n書式が無効化されており、使用できなくなっている[9]

また、書式化文字列中の書式指定子と実引数の数や型が正しく対応していない場合は未定義動作を引き起こす。Cの可変長引数は型消去によって実現される仕組みであるため、printf()の内部では書式と実引数の数や型の不一致を検出することができず、本質的に安全性が欠如している。正しい書式を与えることはプログラマ側の責任である。

なお、引数で受け取ったバッファに書式化された文字列を出力する関数群は、バッファサイズを超えてデータを書き込んでしまうと未定義動作を引き起こす。特に、sprintf()vsprintf()といったバッファサイズ(書き込み可能な最大サイズ)を指定することのできない関数は潜在的なバッファオーバーフローの脆弱性を抱えているため使うべきではなく、代わりにC99で追加されたsnprintf()vsnprintf()を使うべきである。

他言語

C言語から派生したC++D言語はもとより、PHP[10]Ruby[11]Perlなど他の言語でもprintfが実装されている。Python 2.xではprintだったが、3.xではprint関数となった。

また、Ruby[12]やPythonなど、%演算子によってsprintf()相当機能をサポートするものも存在する。Boost C++ライブラリのBoost.Format[13]では、boost::formatクラスの%演算子オーバーロードによって類似の機能を実現している[14]

C++11ではC99のライブラリ関数の多くが取り込まれた。C++20では関数テンプレートstd::format()[15]が、C++23ではstd::print()[16]が追加された。

Unix系オペレーティングシステムのコマンドとして実装されたprintf英語版もある。外部コマンドのほか、Bashなど一部のUnixシェルではビルトインで実装されている。

Java

Java 1.5ではStringクラスにformat()メソッドが、java.io.PrintStreamクラスにformat()メソッドとprintf()メソッドが追加された。

標準出力の場合は、例えば以下のように呼び出すことができる。

System.out.printf("Integer = 0x%02X, Double = %.4f\n", 10, Math.PI);

Javaの可変長引数はObjectの配列だが、intdoubleのようなプリミティブ型の引数はオートボクシング(自動ボックス化)によってプリミティブラッパークラスにラップされて渡されるため、オーバーヘッドはあるものの本質的に型安全である。書式指定に誤りがあった場合はjava.util.IllegalFormatException例外を、また書式指定に対応する実引数が不足していた場合はjava.util.MissingFormatArgumentException例外をスローする。

Javaに限らず、後発のオブジェクト指向言語や動的型付け言語の場合は、可変長引数として使われるコレクション(配列やリスト)が長さ情報を持っており、またコレクション中の各オブジェクトが自分自身の型情報を持っているため、printf()相当機能がバッファ安全かつ型安全に実現できるようになっている。


注釈

  1. ^ 実際のローカライズ作業では、gettext等によってメッセージカタログから文字列を得るようにコードを記述する。
  2. ^ 類似の順序指定可能な書式化機能を持つものとして、Windows APIFormatMessage()関数や、Microsoft Foundation ClassAfxFormatString2()関数、.NET FrameworkSystem.String.Format()メソッドなどが挙げられる。
  3. ^ 可変長引数では「既定の実引数拡張」により、float型の引数はdouble型へと変換されるため、本来はdoubleに対して修飾子を適用する必要はない。
  4. ^ 例えばLP64環境ではlong64ビットであり、仮にint64_t型の実引数に対して%ld書式を使用したとしてもほとんどの実装では期待通り動作する可能性が高いが、LLP64環境ではlong32ビットであり、int64_t型の実引数に対して%ld書式を使用すると未定義動作を引き起こす。また、long longは少なくとも64ビット以上の値を表現できることが保証されているが、int64_tと同じ型であるという保証はどこにもなく、int64_t型の実引数に対して%lld書式を使用した場合の動作はやはり未定義となる。同様に、intint32_tが同じ型であるという保証もない。
  5. ^ Microsoft Visual C++には非標準関数としてバッファサイズを受け取らないswprintfが存在するが、バージョン2005 (8.0) 以降では既定で無効化されており、非推奨となっている[3][4]

出典



「printf」の続きの解説一覧




固有名詞の分類


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「printf」の関連用語

printfのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



printfのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアのprintf (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。

©2024 GRAS Group, Inc.RSS