sprintf関数 - フォーマット文字列を文字列変数へ出力
sprintf関数は、フォーマット文字列を、文字列変数へ出力できる関数です。printf関数は、標準出力に対して出力しますが、この出力先をchar型の配列として宣言された文字列変数に変更するものがsprintf関数だと考えてください。sprintf関数は、stdio.hを読み込むと利用できます。
#include <stdio.h> int sprintf(char *str, const char *format, ... );
第一引数は、出力先の文字列です。第二引数はフォーマット文字列で、printf関数で解説したものと同じものです。第三引数以降は、可変長引数で、printf関数で解説したものと同じものです。
sprintf関数は、バッファオーバーランを起こす可能性のある関数です。
sprintf関数のサンプル
sprintf関数のサンプルです。
#include <stdio.h> #include <stdint.h> int main(void) { const char* name = "kimoto"; int32_t age = 40; char message[255]; sprintf(message, "I'm %s. Age is %d.", name, age); printf("%s\n", message); }
出力結果です。
I'm kimoto. Age is 40.
このサンプルでは、バッファオーバーランを起こすことはありません。
sprintf関数とバッフォオーバーラン
sprintf関数とバッフォオーバーランの危険性について書きます。
たとえば、ユーザーの入力によって、フォーマットに埋め込む値が変わると考えてください。たとえば、Web入力フォームで、ユーザーの名前に長さ制限をかけていなかったとします。また、出力先の文字列の長さが短いものだったとします。
#include <stdio.h> #include <stdint.h> int main(void) { const char* name = "long_long_long_name"; int32_t age = 40; char message[16]; // バッファオーバーラン!!! sprintf(message, "I'm %s. Age is %d.", name, age); printf("%s\n", message); }
バッファオーバーランが発生すると、意図しないメモリ領域に、データが書き込まれます。これが、具体的個別にどのような問題を起こすかは、僕は詳しくないので、セキュリティエンジニアの方に委ねます。プログラムを記述するエンジニアとしては、バッフォオーバーランを起こしてはならないということを覚えておきましょう。
最大書き込み数を制限できるsnprintf関数もありますので、用途によって使い分けましょう。