IFS

21. ストリーム・ファイルと CCSID の考慮

ストリーム・ファイルを扱うようになれば CCSID を考慮する必要がある。

先に説明した RPG での open 命令の

/FREE
FD = open('/tmp/hello.txt': O_CREAT + O_TRUNC + O_WRONLY + 
           O_CCSID : O_RDWR : EBC_CCSID);
/END-FREE

では EBC_CCSID は int 型でファイルの CCSID として指定しなければならない。
もし CCSID の指定がなくて

/FREE
FD = open('/tmp/hello.txt': O_CREAT + O_TRUNC + O_WRONLY + O_RDWR);
/END-FREE

と記述して実行したとすると、このファイル: /tmp/hello.txt の CCSID は
この実行ジョブの CCSID が採用されてしまう。
つまり多くの場合は CCSID = 5026, 5035 または 1399 である。
ところがストリーム・ファイルに書き込むデータは実際は ASCII であるので
CCSID : 5026 のファイルに ASCII つまり CCSID:819 のデータを書き込んだのでは
意味不明になってしまう。
英文の文章にこれは韓国語です、と言っているようなものである。

ところで CCSID : 1399 と UNIコードとは全く無関係であると改めてここで
説明しておく。
特約店の SE や IBM SE が書いたと思われる個人サイトでも
CCSID:1399 は UNI コードであると説明している誤りがあまりにも多く
未だ訂正されていない。
UNIコードの漢字は 3バイト、EBCDIC の漢字は 2バイト。
これだけでも違っているのに CCSID を 1399 に変更すると EBCDIC の漢字コードが
変わるなんてことはあり得ない。

CCSID : 1399 は UNI コードではない。

CCSID:1399 は UNI コードです、と説明する SE はまず信用がおけない。
CCSID:1399 とは CCSID:5035 に NEC 選定漢字を加えた
れっきとした EBCDIC コードである。

UNI コードの CCSID は、UTF-16 は 1200 であり、UTF-8 は 1208 である。
さらに ASCII の CCSIDは 819 である。

ここで注意が必要なのは UNI コードである。
UNI コードは私たちが使っていた英文字を始めとする半角文字は 2バイトで表し(UTF-16)
漢字コードは 3バイトで表す。

先に char* とは NULL-STOP で終了する、と説明したが UTF-16 では漢字などに
NULL 文字( X'00') が含まれている。
従って UNI コードを扱うときは char* をうかつに信用してしまうと
文字列の途中が脱落してまうということになりかねない。
もちろんプログラマーは最初はデータが途中で欠落しているのではないかと
疑うかも知れないがそれは UNI コードで char* として定義してしまったことが
原因である。
UNI コードを扱うときは必ず長さも合せて変数を定義しないとこのトラブルに
陥りやすいので注意が必要である。