- ベストアンサー
COBOL・全角判定
以前こちらで質問したものです。 http://oshiete1.goo.ne.jp/qa2553484.html 例題を参考に詳細設計書を作成中ですが、 お客様の要望で「漢字項目は前後に漢字制御コード(前に‘0A42’後に‘0A41’)を付加する」というのがあり、わからなくなってしまい質問です。 漢字項目もX(40)というようにCOPY句で設定されています。 どの項目が漢字項目なのかは資料をいただいてわかっています。 例題をもとにすると IF DATA-AREA NOT = ' ' PERFORM TEST BEFORE VARYING I FROM DATA-LEN BY -1 UNTIL (I < 1) OR (DATA-AREA(I:1) NOT = ' ') CONTINUE END-PERFORM 【1】 MOVE I TO DATA-LEN STRING DATA-AREA ',' DELIMITED SIZE INTO OUT-REC WITH POINTER DATA-POS END-STRING 【1】にIF文でデータが全角かどうか判定するのだと思うのですが どう判定したらよいのでしょうか。マニュアルをみたのですが探せませんでした。またもし全角データだった場合STRINGはどのように記入すればよいのでしょうか。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
#3、#4回答者です。 少し勘違いしていたかも知れません。 X(40)の項目に、漢字データがX'0A42'、X'0A41'抜きで入っているのですか? もしそうなら、「後方の半角スペース取り除く」とのことでしたが、データの終端は分かるのでしょうか?この場合は、「全角のスペースを取り除く」ということになるのでしょうか? データの中身を見て、全角のコードか否かを判断するのは容易ではなく、またチェックのためのオーバヘッドが発生します。全角データか否かをフラグで引き継ぐ方が、簡単な処理にできると思います。 77 KANJI-FLG PIC S9(1) COMP. 77 KI PIC X(2) VALUE X'0A42'. 77 KO PIC X(2) VALUE X'0A41'. ~中略~ * MOVE 1 TO KANJI-FLG. COMPUTE DATA-PTR = FUNCTION ADDR(ITEM1). COMPUTE DATA-LEN = FUNCTION LENGTH(ITEM1). PERFORM DATA-EXTRACT. * MOVE 0 TO KANJI-FLG. COMPUTE DATA-PTR = FUNCTION ADDR(ITEM2). COMPUTE DATA-LEN = FUNCTION LENGTH(ITEM2). PERFORM DATA-EXTRACT. * ~中略~ * 以下の後方の半角スペースを取り除く処理で、 * 全角データの場合、X'0A42'、X'0A41'が入ってないなら、 * 終端は分かる??? IF DATA-AREA NOT = ' ' PERFORM TEST BEFORE VARYING I FROM DATA-LEN BY -1 UNTIL (I < 1) OR (DATA-AREA(I:1) NOT = ' ') CONTINUE END-PERFORM MOVE I TO DATA-LEN IF KANJI-FLG = 0 STRING DATA-AREA ',' DELIMITED SIZE INTO OUT-REC WITH POINTER DATA-POS END-STRING ELSE STRING KI DATA-AREA KO ',' DELIMITED SIZE INTO OUT-REC WITH POINTER DATA-POS END-STRING
その他の回答 (4)
- chukenkenkou
- ベストアンサー率43% (833/1926)
#3回答者です。 分かりにくい部分があったので、追記します。 【変更前】 STRING命令でも、半角だとか全角だとか意識せず、半角データとしてCSVデータを作ってしまえばいいと思いますが? 【変更後】 STRING命令でも、半角だとか全角だとか意識せず、半角データとしてX'0A42'とX'0A41'も含めてCSVデータを作ってしまえばいいと思いますが?
補足
お客様から回答があり ひとつのフィールド内に、漢字と英字は混在しないことになっているので、 「フィールドの末尾から当該位置の文字コードが 0x40 でない間ループする」というチェックを行い、データの切り出し位置を求めればいいはずです。 との事でした。 ですので、#5のような構文でいいのでしょうか。
- chukenkenkou
- ベストアンサー率43% (833/1926)
前回の質問で、コーディング例を提示したものです。 全角か半角かを判定しなければならない理由は、何でしょうか? PERFORMでデータの後方からループさせ、後方の半角スペースは除く処理にしています。もし全角データがあれば、今回はX'0A42'+データ+X'0A41'とのことですので、ループはX'0A41'のX'41'を検知した時点で停止します。 STRING命令でも、半角だとか全角だとか意識せず、半角データとしてCSVデータを作ってしまえばいいと思いますが? 「X'0A42'+データ+X'0A41'」を、変なところで改行したりしなければ、文字化けすることもありません。 ちなみに、半角スペースはX'40'、全角スペースはX'4040'またはX'A1A1'という文字コードです。全角は必ず「X'0A42'+データ+X'0A41'」となっているなら、後方から半角スペース(X'40')を探して取り除くという処理で問題ないと思います。 今回は不要と感じますがSTRING等で、1バイト単位でなく全角単位で操作する場合は、コンパイラオプションで指定可能だったと思います。
- ultraCS
- ベストアンサー率44% (3956/8947)
私は、FORTRANのエンジニア/研究者でCOBOLは#1の方より触ってない(COBOL74まで)のでちょっと自信ないですが 汎用機の場合、COBOLでも癖があるので、出来ればターゲットホストとOSを書いた方がいいですよ。 で、KI/KOが0A42h/0A41hということからしてHITAC VOS1/3あたりですよね。 EBCDIK(日立だからね)の場合、漢字はJIS+8080hで表現され、KI/KOが無いと、EBCDIKではANKと漢字は同じコードが被るので区別できません。 お客様の要求がファイル出力時にKI/KOをつけてくれというのか、入力設計段階でKI/KOがついているというのかがわからないのですが、少なくとも、内部の漢字領域は+4とっておけばいいと思います(大概は有効長が4短くなる場合が多いけど)。 そのフィールドがANK/漢字混在でかつフォーマット不定の場合、KI/KOが複数になるので、プリプロセスで何らかの処理をしないと無理でしょう。極端な話、一1二2三3四4なんてのが来ると、これだけで、28バイト(KI一KO1KI二KO2KI三KO3KI四KO4となるので)になってしまいます。ファイル設計者がホストを知っていれば、おそらくは2バイトコード固定フィールドだと思いますが、PCしか知らないと酷い目にあいますのでご注意。
- PED02744
- ベストアンサー率40% (157/390)
COBOLは20年以上触ってないのでわからないですが(^_^;) これは、JIS句点漢字を使っているということですか? そのX(40)の中に含まれている文字は『すべて漢字』ということでよいのでしょうか? もしそれならば、DATA-LENが36以上ならエラー(shift-in/outで4バイト使うから) 36文字以下だったら、 DATA-LEN+4に0x41, DATA-LEN+3に0x0A, DATA-LEN~1バイト目のデータを DATA-LEN+2~3バイト目に2バイトずつずらす 1に0x0A,2に0x42を入れる とすることでOK もし、句点JIS漢字で「あいうABCえお」のようになっているのだとしたら、シフトイン・シフトアウトを後からつけるのは無理です。 漢字じゃない部分と区別がつかないので。 そうではなくて、Shift_Jis等の漢字コードを使っているが、漢字としての扱い部分の前後に、シフトインアウトをつけたいということなら、 「あいうABCえお」は、「(shift-in)あいう(shift-out)ABC(shift-in)えお(shift-out)」となるので、 単純に前後に入れるだけではだめで、漢字コード表を意識したつくりにする必要があります。
補足
回答ありがとうございます。 その通りです。 入力データではX'0A42'、X'0A41'抜きで入っているので、CSVファイルを作成する時に付加してほしいという要望です。 全角空白、データ途中の半角空白は削除しないとの事ですが、終端がわかるかどうかはちょっと不明です。担当者様に質問してみます。またわかりましたら補足にて報告します。