!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> C プログラミングの落とし穴

C プログラミングの落とし穴

学生に質問されたりしたことのメモ書きなのだ


sprintf の誤った使い方

Q 次のプログラムが期待したとおりに走らない。どうしてでしょう?


#include <stdio.h>
#include <string.h>
void main()
{
 char a[15], b[]  = "abc";
  int n = 12;
  strcpy(a,b);
  sprintf(a,"%s%d",a,n);
  puts(a);
}

A これは,sprint の第3引数 a と第4引数 b を使って,文字列 "abc12" をつくり,第1引数の a に代入しようということですね。意図は分かりますが, これは ANSI で規定された正しい書法ではありませんので,期待通りになる 保障はありません。

この発想はおそらく,


a = a + b
という形の代入のやり方から思いついたものでしょう。 しかし, = は代入演算子であって,この場合は,a + b という計算の結果が出たら,それを a に書き込む仕掛けです。 言ってみれば = の右と左は別の世界なのです。

しかし,sprintf(c,"%s%d",b,n) という関数を考えると,sprintf 関数の実行中に c, b, n は一 緒になって処理されているはずです。 そのため採用されているアルゴリズムによっては, sprintf(a,"%s%d",a,n) などとすると, a が途中で破壊されてしまうかもしれません。 上のような使い方は想定されていないのです。

sprintf の正しい使い方は次の通りです。

#include <stdio.h>
#include <string.h>
void main(){
  char a[15], b[]  = "abc", c[15];
  int n = 12;
  strcpy(a,b);
  sprintf(c,"%s%d",a,n);
  puts(c);
}