😎
C言語でSJISを使用してはいけない理由
この記事では,SJISでコーディングすることのデメリットを説明しています.
なぜダメなのか
問題のコードとエラー
例としてこのようなコードがあるとしましょう.(SJIS)
hello_wowrld.c
#include <stdio.h>
int main(void){
// 数字表
int num[3]={1,2,3};
printf("%d\n",num[0]);
// 与えられた変数と文字列を表示する機能
printf("%d\n", num[0]);
return 0;
}
これを実行すると,こんなエラーが出ます.
$ gcc hello_world.c -w -o hello
hello_world.c: In function ‘main’:
hello_world.c:7:19: error: ‘num’ undeclared (first use in this function)
7 | printf("%d\n",num[0]);
| ^~~
hello_world.c:7:19: note: each undeclared identifier is reported only once for each function it appears in
原因
さて,numは宣言されているのに,されていないことになっていますね.
理由は直前にあるコメントです.
表
のSJISコードは149 92
で,この92
はSJISで\
となります.
\
は,その次の行は、この行の続きである という意味を示します.
そのため,
// 数字表
int num[3]={1,2,3};
は,(アバウトに表現するならば)
// 数字表 int num[3]={1,2,3};
として,解釈されます.
だからnumが宣言されていないこととなるのです.
では,このコメントを消去して実行してみましょう.
問題のコードとエラー part2
コメントを消去したプログラムはこうなりますね.
hello_wowrld.c
#include <stdio.h>
int main(void){
int num[3]={1,2,3};
printf("%d\n",num[0]);
// 与えられた変数と文字列を表示する機能
printf("%d\n", num[0]);
return 0;
}
実行結果はこんな感じ
$ gcc hello_world.c -w -o hello
$ ./hello
1
これを実行すると,エラーは出ないものの,2回表示されませんね.
原因は,やはりコメントにあります.
能
のSJISコードは149 92
で,この92
はSJISで\
となります.
\
は,先ほども申し上げた通り,その次の行は、この行の続きである という意味を示します.
つまり解釈としては,(アバウトに表現すると)
// 与えられた変数と文字列を表示する機能 printf("%d\n", num[0]);
となってしまうため,エラーではないものの,想定した挙動をしてくれないわけです.
では,このコメントを消去してもう一度実行してみましょう.
対策
hello_wowrld.c
#include <stdio.h>
int main(void){
int num[3]={1,2,3};
printf("%d\n",num[0]);
// 与えられた変数と文字列を表示する機能
printf("%d\n", num[0]);
return 0;
}
ようやく想定した挙動をしましたね!
このように,SJISだとコメントのせいでエラーが出たり,想定している挙動をしなかったりするわけです.
今回紹介した表や能以外にも,噂 十 申 などがあります.(これらを総じてダメ文字とか言ったりします)
対策として,以下のような方法があります.
- UTF-8等を使用する(著者推奨)
- コメントの最後に「.」を必ず追加する
- gccのオプションに
--input-charset=cp932
を追加する(UTF-8として読み込ませる)
Plus
たまにプログラマー界隈で聞く
//このコメントを書いたらなんかうまくいった
っていうのは,これが原因ですね.
Discussion