2014年3月18日火曜日

関数の落とし穴



シングルバイト専用の関数に、マルチバイト文字を含む引数を指定しちゃダメという話です。
今回の内容はWindowsのSAS9.3 日本語 (shift-jis) の環境下での結果とします。他の環境下では挙動が異なります。


上記環境下で以下のプログラムを実行すると変数BとCの値は変わった動きをします。

data DT1;
   length A B $20.;

   A = "予防";
   B = compress(A, "\");
   C = index(A, "\");
run;

結果
A        B         C
予防    蘭h       2



これは文字コードが関係しています。この辺は詳しくないですが、
  • "予防"の"予"という字は文字コードだと「975C」、
  • "\" は文字コードだと「5C」になるようです。

「5C」の部分が共通なので、"予" に "\" が入っているものとして扱われてしまいます。
「5C」に限らず、マルチバイト文字だと上記のように文字コードで見たときに共通する部分が出てきてしまうため、関数の結果がおかしくなります。


たとえば以下の場合とかもおかしくなるはず。
「VAR1 = compress("右", "E");」


これを回避するのが、「K」を頭につけたマルチバイト対応の関数達です。
data DT2;
   length A B $20.;

   A = "予防";
   B = kcompress(A, "\");
   C = kindex(A, "\");
run;

結果
A        B        C
予防    予防    0



注意点として、以下の例のように、シングルバイト専用の関数はバイト数で判断するのに対して、K関数達は文字数で判断します(K関数でもバイト数で判断するものもある)

 INDEX("あいう","い") -> 3
 KINDEX("あいう","い") -> 2

0 件のコメント:

コメントを投稿