2016-03-29 9 views
0

私は大きすぎるチャンクの問題を攻撃する傾向があることがわかったので、私の はより小さくより具体的なものから始めようとしています。Cobol - PIC Nフィールドのコンテンツの長さと位置はどのようにして決められますか?

私はPIC Nフィールド(Nationalフィールド)と排他的に作業しています。私が取り組んでいるプログラムのために、そのフィールドのコンテンツの長さと位置を決定する必要があります。

次のように私が話している特定のフィールドが定義されている:

05 Bank-CODE PIC N(10).

スペースがありますリードすることができ、スペースが末尾することができます。埋め込みスペースについても、ある時点でテストする必要があります。

基本的な目標は、このフィールドの内容をスペースなしで処理できるようにすることです。

は今、私はフィールド自体の長さを決定する方法を知っている: 05 BANK-CODE PIC N(10). 05 BK-LENGTH PIC S9(04) COMP. MOVE LENGTH OF BANK-CODE TO BK-LENGTH COMPUTE BK-LENGTH = FUNCTION LENGTH (BANK-CODE)

私はちょうどBANK-CODEのコンテンツの長さと位置を決定する方法がわかりません。

+0

に行った事が、あなたが使用しているコンパイラおよびオペレーティングシステムを教え:-) –

+0

をなぜすべてのデータナショナルはありますか?あなたは実際にアルファベットでも数字でもない文字の可能性を持っていますか? –

+0

良い質問。なぜ私たちがナショナルを使っているのかわかりません。私の最初の解釈は、私のインプットとアウトプットがナショナルであれば、私が望むものを作業用ストレージに入れることができたということでした。その後、私は上級開発者の同僚に尋ねました。彼は、WSセクションを含め、ほとんどすべてにナショナルを使用しなければならないと述べました。 – Lena

答えて

4

あなたが探しているのは、「トリム」、またはフィールドの先頭と末尾のスペースをトリミングするための情報です。

COBOLにはありません。前に述べたように、あなたはGnuCOBOLのようなコンパイラを使っています。しかし、私はあなたがIBMのエンタープライズCOBOLを使用していると思います。もしあなたがそうであれば、名前と特定のバージョンが、コンパイラの出力リストの各ページの上部に表示されます。

COBOLにはトリムがないので、あなたを止めません。つまり、コードが必要なだけです。

ここで、「そこ」からいくつかのだ(S8833TR.pdfための検索エンジン、リンクは長い話、長い)と顧客の状況からコーディングのヒントのセクション見つける:

MOVE ' This is string 1 ' TO TEXT1 
COMPUTE POS1 POS2 = 0 
INSPECT TEXT1 
    TALLYING POS1 
    FOR LEADING SPACES 
INSPECT FUNCTION REVERSE(TEXT1) 
    TALLYING POS2 
    FOR LEADING SPACES 
MOVE TEXT1(POS1:LENGTH OF TEXT1 - POS2 - POS1) 
TO TEXT2 

をと

MOVE ' This is string 1 ' TO TEXT1 
PERFORM VARYING POS1 FROM 1 BY 1 
    UNTIL TEXT1(POS1:1) NOT = SPACE 
END-PERFORM 
PERFORM VARYING POS2 FROM LENGTH OF TEXT1 
    BY -1 UNTIL TEXT1(POS2:1) NOT = SPACE 
END-PERFORM 
COMPUTE LEN = POS2 - POS1 + 1 
MOVE TEXT1(POS1 : LEN) TO TEXT2 (1 : LEN) 

あなたはあなたが言われたように、FUNCTION REVERSEといくつかのパフォーマンスの含意を(コードの最初のブロックが第二より31%遅い)があり、文書内の参照が、それを回避する上で注意が必要だろう。実行するのが遅い場合は、コード化し理解する方が簡単です。あなたのサブプログラムがであるをたくさん使用する場合は、パフォーマンスを考慮する価値があります。

コードは、IBMのTom Rossによって提供されています。

トムのコードでは「参照の変更」が使用されています。これは、コンパイル時(開始位置と長さがわかっている場合)、または開始位置と長さのいずれかまたは両方が可変であれば、実行時にフィールドのサブフィールドを定義できる方法です。参照の変更は、データにアクセスする非常に高速な方法です。コードを難読化するデータにアクセスすることは、非常に怠け者で控えめな方法でもあります(そこには少しだけ意見が出ているかもしれません。

代わり基準変更により、このようなコード使用何かの次片:

 01 the-text      PIC X(30). 
     01 FILLER 
      REDEFINES the-text. 
      05 FILLER 
       OCCURS 30 TIMES. 
       10 the-byte-of-text  PIC X. 

-バイトのテキストは、次に、むしろグループ項目よりも、添字で参照することができる(テキスト)が参照されています。

POS1は、参照変更とサブスクリプトで同じように定義されている可能性があります。それは可能です。私はPIC 99バイナリ(バイナリ/ COMP/COMP-4はエンタープライズCOBOLと同じです)に行くでしょうが、あなたの同僚はPIC S9(4)COMP(古い習慣は大荒れている)を主張するかもしれません。

さて、あなたはさらに速くそれをしたい場合:

 PERFORM 
     VARYING     POS1 
      FROM      1 
      BY      1 
     UNTIL      (NOT TEXT1-BYTE-IS-SPACE 
             (POS1)) 
     END-PERFORM 
     MOVE TEXT1 (POS1 :)  TO TEXT2 

をトムのコード、TEXT2の初期設定から欠落部分は、実際にあります。

このコード(mine)は、リファレンス変更で「長さ」を使用しないことでこれを処理します。何故なの? COBOLフィールドは可変長のものを除いて固定長であるため、末尾のスペースを "取り除く"ことはできません。その例では、末尾のスペースを見つけるのは面倒ではなく、前回のコード実行からTEXT2にデータが残っていないことを確認するために最後のMOVEを使用します(Tomの例のようになります)。

私はREDEFINESとデータ名をサブスクリプト(POS1)と88レベルの条件名として使用しました。高速化するだけでなく、コードをより明確にすることができます。限界内では、両方を同時に行うことができます。

あなたのタスクのために、あなたはは、末尾のスペースの長さを知りたいですか:例と

一つの問題は、多くの場合、彼らが欠落していた初期化のように、完全ではないということです。完全ではないもう一つのことは、すべてのコードで、少なくとも1つの非空白の存在があると仮定していることです(リテラルがソースとして使用されるため)。それはしばしば非現実的であり、あなたの場合はまったく役に立たない。

PERFORMの終了条件で「終了していないことを確認してください」を含めることで、より一般的なケースでよく対処します。しかし、複数の条件は理解しにくく、実行が遅くなります。

 IF field-in-use-is-blank 
      PERFORM     no-field-to-deal-with 
     ELSE 
      PERFORM     field-to-deal-with 
     END-IF 

すぐに2つの異なるケースを作成します。フィールド対処では、少なくとも1つの空白以外の文字があることがわかります。フィールドではないフィールドでは、フィールド全体が空白であることがわかります。

field-in-use-blankは、フィールド上の88レベルの条件名です。

01 your-field       PIC X(40). 
     88 field-in-use-is-blank   VALUE SPACE. 

ここで使用した名前は説明用です。私はあなたの実際の目的のために意味のある名前を常に提案します。

 PERFORM 
     VARYING     POS2 
      FROM      LENGTH OF TEXT1 
      BY -1 
     UNTIL      (TEXT1-SPACE-CHECK 
             (POS2) 
            NOT EQUAL TO SPACE) 
     END-PERFORM 
     COMPUTE LEN     = (POS2 
             - POS1) 
             + 1 

フィールドの最後から後ろに行くと、88レベルは使用できません。

今、あなたはLENを持っています。私はすべてのものに異なる名前を使用しますが、それは私です。ここで

は、関連するデータ定義です:

01 FILLER REDEFINES TEXT1. 
     05 FILLER OCCURS 50 TIMES. 
      10 TEXT1-SPACE-CHECK   PIC X. 
       88 TEXT1-BYTE-IS-SPACE  VALUE SPACE. 

    01 LEN       COMP PIC S9(4). 
    01 POS1       COMP PIC S9(4). 
    01 POS2       COMP PIC S9(4). 

TEXT1はわずか50バイトのPICのXフィールドでした。卵を皮膚に塗布する方法はたくさんあります。上記のコードは、POS1が参照変更で使用される方法と、添え字として使用される方法を示しています。 LEN、POS1、POS2のサイズとタイプは、最も推測されたものでした。彼らはすべてバイナリ(私はモダンにしてみましょう。それはちょうどタイピングのものなので...)PIC 99。その定義が元のものよりも効率的である場合、そうでなければ同じ場合があります。あなたの高齢者のいずれかを納得させることを期待しないでください。

COBOLは、主に「チーム」のことです。物事はあなたのサイトで行われるようにしてください。ローカルの「標準」が貧弱なものや古くなったものは、いつでも変更することができます。明らかに意味のある名前を使用することは、それ自体が利点であり、それは技術に関連していません。

上記はPIC X(またはPIC Aですが、そうは見えないでしょう)フィールドです。 PIC Nでは何が違うのですか? LENGTH OFの代わりにちょうどFUNCTION LENGTH

しかし、PIC Nに潜在的なパフォーマンスの問題があります。必要に応じて、必要に応じて、コンパイラはNationalを英数字に変換して元に戻します。パフォーマンスだけでなく、数値とプレーンなアルファベットのアルファベットでは、最後の瞬間にすべてをPIC Nに変換します。そしてそれは単純なMOVEのように少なくても、コンパイラによってコードが生成されます。

はあなたがすでにだけでなく、「トリマー」へのリンクが示されたことを追加するのを忘れ:https://codereview.stackexchange.com/q/69220/21548

+0

あなたの精巧な答えをありがとうございます。私は気が狂っているかもしれませんが、私はあなたのPOS1とTEXT1-SPACE-CHECKに含まれているものは得られません。それを私に説明してもらえますか?私はコーディングとコボルへの完全な初心者ですが、私はコースを持っていましたが、今のところ間違いなく気づいたように、私はまだかなりのことで苦労しています。 – Lena

+0

あなたの時間をもう一度ありがとうBill :-)緻密化については、それは物事を少しはっきりさせましたが、私はあなたが書いたコードの最後のビットでまだ少し苦労しています。私はちょうどPOS1の値が宣言されたり、塗りつぶされたりすることがないので、POS2から差し引いたときに役立ちます。 TEXT1-SPACE-CHECKも同じです。私はそれを認めて恥ずかしいですが、私はそれがどのように動作するのか分かりません。私はあなたのようなベテランのためにイライラすることができると思うので、あなたが私にrtfmフレーズを投げたいなら、私は理解しています – Lena

+0

こんにちはビル、あなたを迷惑してすみませますが、TEXT1-SPACE-CHECKこの回答に投稿したコードの最後の部分にPOS1とPOS1があります。本当に便利だから、時間があれば分かります。 – Lena

関連する問題