2

テキスト フィールドと数値フィールドが混在する COBOL の「テープ形式」ダンプがあります。C# でファイルをバイナリ配列 (バイトの配列) として読み取っています。私はコピーブックを持っており、フォーマットはテキストフィールドにうまく並んでいます. COMP-3 フィールドもいくつかあります。これらのフィールドのデータは、BCD 形式と一致していないようです。私はデータがどうあるべきかを知っており、COMP-3 の生のバイトを持っています。最初に EBCDIC に変換しようとしましたが、良い結果は得られませんでした。それ以外の方法で COMP-3 番号を内部に保存する方法について何か考えはありますか? 以下は、PIC、生データ、および予想される数の 3 つの例です。数字の両側にアルファ データがあり、すべてが正しく並んでいるので、フィールドの位置が正しいことはわかっています。

最初の例: フィールドの PIC は 9(9) COMP-3 データには 5 バイトあり、16 進値は 02 01 20 91 22 です。結果のデータは日付 (00CCYYMMDD) になります。この特定の日付は 3-17-14 である必要があります。

2 番目の例: フィールドの PIC は S9(3) COMP-3 データには 2 バイトあり、16 進値は 0A 14 結果の値は 900 から 999 の間である必要があります。最後のニブルは、+ または - を示すために 0xC または 0xD である必要があります

3 番目の例: フィールドの PIC は S9(15)V99 COMP-3 です データには 9 バイトがあり、16 進値は 00 00 00 00 00 00 01 80 0C です 結果の値は 12.00 になるはずです

正しい方向に私を向けてくれたので、回答してくれた人々に感謝します。これは確かに ASCII/EBCDIC 表現の問題です。BCD は EBCDIC に格納されます。ASCII から EBCDIC への変換テーブルを使用すると、適切にフォーマットされた BCD 数字が生成されます。

このリンクを使用してデータをマッピングしました: http://shop.alterlinks.com/ascii-table/ascii-ebcdic-us.php

私のデータ: 0A 14 変換済み: 25 3C (253 は有効な値であることがわかりました。仕様は間違っていました) C = +、すべて良好

私のデータ: 01 80 0C (先頭のゼロを除く) 変換: 01 20 0C 12.00 C = +, 暗黙の 2 桁の形式, すべて良好

私のデータ: 02 01 20 91 22 変換済み: 02 01 40 31 7F 2014/03/17 (F は未使用のニブル)、すべて良好

4

5 に答える 5

3

というようなものはありませんがCOBOL "tape format"、そのフレーズはデータを提供した人にとって何かを意味する場合があります。

あなたの問題の手がかりは、テキストを読むことができるということです。それを EBCDIC タグと C# への参照に接続します。

したがって、ASCII の代わりに EBCDIC を使用するメインフレーム (おそらく IBM メインフレーム) からの元のデータを読み取っています。

COBOL には BCD のネイティブ サポートがありません。

親切な魂があなたのためにしたことは、データを EBCDIC から ASCII に「変換」することです。そうしないと、「テキスト」さえ認識できません。

残念ながら、2 進数、パック 10 進数、または浮動小数点フィールド (最後のフィールドはあまり表示されませんが、COMP-1/COMP-2 です) の場合、「変換」は「潜在的にスクランブルされる」ことを意味します。これは、カバーが個々のバイトを単純なバイト値で想定しているのに対し、これらのフィールドはすべて、複数のバイトまたは非 EBCDIC 値、またはその両方を介して従来のコーディングを使用しているためです。

そう: COMP-3 PIC 9(9)。おっしゃる通り、5バイトです。これは符号なしであるため、右端のニブルは F (すべてのビットがオン) になります。符号のないフィールドであっても、符号の位置が占有されているため、位置がわずかにずれています。

メインフレームでは、値が含まれていますX'020140317F'。そのフィールド全体だけが、その値に関して何らかの意味を持ちます。ただし、EBCDIC から ASCII への変換により、X'0201209122' になりました。

どのように?

X'02'との EBCDIC 値を調べますX'01'。彼らは変わりません。の値をX'40'調べて、それはスペースです。ASCII に変更しX'20'ます。の値を調べますX'31'。実際には特別なことはなく、 よりも高いものに変換されていX'7F'ますが、使用されている変換テーブルを見れば、なぜそれが起こるのかがわかると思います。はX'7F'二重引用符なので、 に変更されX'22'ます。

あなたが示す他の値も同じ問題を抱えています。

メインフレームからデータのみを文字のみの形式で取得する必要があります。ここには多くの答えがありますrelated。右側を見てください。

この最近の質問を見てください: COMP および COMP-3 パック 10 進数を C で読み取り可能な値に変換する

于 2014-04-02T14:08:15.663 に答える
1

私はこれに少し遅れていますが、あなたの人生を楽にするかもしれないいくつかの提案があります...

まず、ダウンロードする前に、すべての非文字 (つまり、2 進数とパック 10 進数) データを表示形式 (PIC X など) に変換するメインフレーム コンターパーツを取得できるかどうかを確認します。次に、0 から 9 を表す「印刷可能な」範囲の数字のみを処理する必要があります。印刷可能な文字のみのコード ページ変換はかなり標準的であり、それほど失敗することはありません。コピーブックを使用してデータを再フォーマットすることは、メインフレーム環境に習熟している人にとって難しいことではありません。残念なことに、「回避策」が取られることがあり、非常にコストがかかる、特別なソフトウェアが必要である、またはその他の何百もの偽りの言い訳のいずれかが主張されます。

「回避策」が発生した場合、次善の策は、ファイルをバイナリ形式でダウンロードし、文字データに対して独自のコードページ変換を行うことです (かなり簡単です)。次に、コピーブックの定義に基づいてバイナリ データを処理します。いくつかの Google を使用すると、PACKED-DECIMAL (COMP-3) データを必要なものに変換するのに十分な情報を見つけることができるはずです。

開始するためのいくつかのリンクを次に示します。

数値データ形式

パック 10 進数

パック 10 進数やその他のバイナリ データをデコードするために、ファイル転送パッケージによって適用されるコード ページ変換をリバース エンジニアリングしようとすることはお勧めしません。

于 2014-04-02T18:03:43.347 に答える
0

わかりました。正しい方向に私を向けてくれたので、応答してくれた両方の人に感謝します。これは確かに ASCII/EBCDIC 表現の問題です。BCD は EBCDIC に格納されます。ASCII から EBCDIC への変換テーブルを使用すると、適切にフォーマットされた BCD 数字が生成されます。

このリンクを使用してデータをマッピングしました: http://shop.alterlinks.com/ascii-table/ascii-ebcdic-us.php

My data:    0A 14
Converted:  25 3C  (turns out that 253 is a valid value, spec was wrong) C = +, all good

My data:    01 80 0C  (excluding leading zeros)
Converted:  01 20 0C  12.00  C = +, implied 2 digits in format, all good

My data:    02 01 20 91 22
Converted:  02 01 40 31 7F     2014/03/17  (F is unused nibble), all good

私を正しい方向に導いてくれた上記の2つの回答に再び感謝します。

于 2014-04-02T17:45:05.253 に答える