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関数もありますので、用途によって使い分けましょう。

関連情報