Optimization 如何在COBOL中将右边的空格替换为左边的零?

Optimization 如何在COBOL中将右边的空格替换为左边的零?,optimization,cobol,Optimization,Cobol,我有一个长度为10的字母数字变量。它的开头包含一个数字,其余数字用空格填充。然后我需要将字符串向左移动,并在开始处添加空格数“0”。这些例子不言自明: INPUT OUTPUT ============================== '123456 ' -> '0000123456' '12345678 ' -> '0012345678' '123456789 ' -> '0123456789' '1234567890' ->

我有一个长度为10的字母数字变量。它的开头包含一个数字,其余数字用空格填充。然后我需要将字符串向左移动,并在开始处添加空格数“0”。这些例子不言自明:

INPUT            OUTPUT
==============================
'123456    ' ->  '0000123456'
'12345678  ' ->  '0012345678'
'123456789 ' ->  '0123456789'
'1234567890' ->  '1234567890'
然后我想到这样的事情:

在您可以尝试的地方检查此COBOL小提琴:(只需单击编辑)

返回:

0000123456

它似乎工作正常,但我想知道您是否有更好、更简单或更清晰的方法来完成它。

您应该使用所有空白输入来测试代码

如果您对数据的质量有绝对的把握,无论是否检查空白,您都可以这样做:

   ID DIVISION.
   PROGRAM-ID. VARSWAP.
   DATA DIVISION.
   WORKING-STORAGE SECTION. 

       01 VARIN   PIC X(10).
          88  NO-VARIN-PRESENT VALUE SPACE.
       01 VARSWAP PIC 9(10).

   PROCEDURE DIVISION.

       MOVE '123456    ' TO VARIN
       IF NO-VARIN-PRESENT
           do what your spec says
       ELSE
           UNSTRING VARIN DELIMITED BY ' ' INTO VARSWAP
       END-IF

       DISPLAY VARSWAP

      GOBACK
      .
我不喜欢破坏输入,所以我改变了

一种流行的方法是,函数反转(你的字段),然后检查反转字段计数。。。用于前导空格。您可以在程序的早期使用函数长度来确定字段的长度(并确保它们的长度相同),然后,首先将VARIN设置为零,对源和目标使用引用修改-源将是(1:计算的数据长度)目标将是(计算的开始,以便正确对齐:)(未指定长度将使用字段的剩余部分)

还有可变长度字段,逐字节移动(有时“传统主义者”更喜欢,但最不清楚)

具体操作方式取决于您的数据。如果您需要验证数据,则首先需要验证数据的代码,这将使您的选择更加明确。如果您的数据是有保证的、干净的,则


我知道这只是一个例子,但我希望你能用更好的数据名来表示真实情况。

如果你有内部函数,可以通过pic 9来调整函数TRIM,根据需要调整前导或尾随。在本例中是尾随,或者在下面的例子中两者都是

identification division.
program-id. rjust.

data division.
working-storage section.
01 str    pic x(10) value '123       '.
01 some-n pic 9(10).

procedure division.

move function trim(str) to some-n
move some-n to str

display some-n, " : ", str end-display
goback.

0000000123 : 0000000123

正如Bill在上面提到的validation,这假设所有空格都等于0。这可能是明智的,也可能不是明智的。非数字也是一个问题。

最简单的方法是在move语句中使用with CONVERSION子句,如果您不确定输入,请添加on EXCEPTION子句

IDENTIFICATION DIVISION.
PROGRAM-ID. ONCONVERSION.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION. 

    01 VARIN  PIC X(10).
    01 VAROUT PIC 9(10).

PROCEDURE DIVISION.
    MOVE '123456    ' TO VARIN

    MOVE VARIN TO VAROUT WITH CONVERSION
    ON EXCEPTION
        MOVE ZERO TO VAROUT
    END-MOVE

    DISPLAY VARIN

    STOP RUN.

我很惊讶没有人建议在这里使用NUMVAL

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  VARIN     PIC X(10).
01  VAROUT    PIC 9(10).
PROCEDURE DIVISION.
    MOVE '123456    ' TO VARIN
    COMPUTE VAROUT = FUNCTION NUMVAL(VARIN)
    DISPLAY '>' VARIN '<'
    DISPLAY '>' VAROUT '<'
    GOBACK
    .
识别部门。
程序ID。示例。
数据司。
工作和储存科。
01 VARIN图X(10)。
01 VAROUT图9(10)。
程序司。
将“123456”移动到VARIN
COMPUTE VAROUT=函数NUMVAL(VARIN)
显示'>'VARIN''VAROUT'比尔·伍德格提到:“也有……逐字节移动(有时“传统主义者”更喜欢,但最不清楚)。”下面是一个我希望相当清楚的解决方案。以下是两个版本。第一个是针对以下建议更新的解决方案。第二个是建议的原始解决方案,以供理解评论时参考。谢谢你,比尔,你的好建议!有一天我可能会学会编写好的COBOL:)

识别部门。
程序ID,右移。
*STACKOVERFLOW.COM上的情况:
*我有一个长度为10的字母数字变量。
*它在开头包含一个数字,其余数字
*都被空格填满了。然后我需要把绳子移到
*左键,并将空格数以“0”开头。
*这些例子不言自明:
*输入输出
* ==============================
* '123456    ' ->  '0000123456'
* '12345678  ' ->  '0012345678'
* '123456789 ' ->  '0123456789'
* '1234567890' ->  '1234567890'
*
*假设输入数据验证在别处完成。
环境司。
输入输出部分。
文件控制。
数据司。
文件部分。
工作和储存科。
图X(10)中的01字符串。
01分线图X(10)。
01字符串长度PIC 99使用组件。
01 CHAR-IN-NUM PIC 99使用补偿。
01 CHAR-OUT-NUM PIC 99使用补偿。
程序司。
梅因。
执行纵向初始化
将“123456”移动到字符串输入
表演化妆秀
将“12345678”移动到字符串输入
表演化妆秀
将“123456789”移动到字符串输入
表演化妆秀
将“1234567890”移动到字符串输入
表演化妆秀
将空格移动到字符串中
表演化妆秀
停跑
.
初始化长度。
将输入字符串的长度移动到字符串长度
如果输出字符串的长度不等于字符串长度
显示'STRING-IN'的长度,'STRING-LENGTH','
'不等于字符串输出的长度,'
串出长度
停跑
端到端IF
.
做秀。
进行编串
前后表演
.
化妆。
将零移动到字符串输出
将字符串长度移动到CHAR-OUT-NUM
字符数
执行字符串长度的时间
如果STRING-IN(CHAR-IN-NUM:1)不=空格
将字符串移入(CHAR-IN-NUM:1)
要输出字符串(CHAR-OUT-NUM:1)
从CHAR-OUT-NUM中减去1
端到端IF
从CHAR-IN-NUM中减去1
末端执行
.
先看后看。
显示“字符串输入:”字符串输入“
显示“字符串输出:”“字符串输出”
显示“”
.
**********************************************
*早期版本,改进之前
*在评论中建议
**********************************************
身份查验司。
程序ID,左移。
*STACKOVERFLOW.COM上的情况:
*我有一个长度为10的字母数字变量。
*它在开头包含一个数字,其余数字
*都装满了SPAC
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  VARIN     PIC X(10).
01  VAROUT    PIC 9(10).
PROCEDURE DIVISION.
    MOVE '123456    ' TO VARIN
    COMPUTE VAROUT = FUNCTION NUMVAL(VARIN)
    DISPLAY '>' VARIN '<'
    DISPLAY '>' VAROUT '<'
    GOBACK
    .
>123456    <
>0000123456<
   IDENTIFICATION DIVISION.
   PROGRAM-ID. SHIFT-RIGHT.
  * SITUATION ON STACKOVERFLOW.COM:
  * I HAVE AN ALPHANUMERIC VARIABLE WITH A LENGTH OF 10. 
  * IT CONTAINS A NUMBER AT THE BEGINNING, THE REST OF THE DIGITS 
  * ARE FILLED WITH SPACES. THEN I NEED TO MOVE THE STRING TO THE 
  * LEFT AND PUT THE NUMBER OF SPACES WITH '0' AT THE BEGINING. 
  * THIS EXAMPLES SPEAKS FOR THEMSELVES:

  * INPUT            OUTPUT
  * ==============================
  * '123456    ' ->  '0000123456'
  * '12345678  ' ->  '0012345678'
  * '123456789 ' ->  '0123456789'
  * '1234567890' ->  '1234567890'
  *
  * ASSUME INPUT DATA VALIDATION DONE ELSEWHERE.


   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.

   DATA DIVISION.
   FILE SECTION.

   WORKING-STORAGE SECTION.
   01  STRING-IN                   PIC X(10).
   01  STRING-OUT                  PIC X(10).
   01  STRING-LENGTH               PIC 99 USAGE COMP.
   01  CHAR-IN-NUM                 PIC 99 USAGE COMP.
   01  CHAR-OUT-NUM                PIC 99 USAGE COMP.

   PROCEDURE DIVISION.
   MAIN.
       PERFORM INITIALIZE-LENGTH
       MOVE '123456    ' TO STRING-IN
       PERFORM MAKE-AND-SHOW
       MOVE '12345678  ' TO STRING-IN
       PERFORM MAKE-AND-SHOW
       MOVE '123456789 ' TO STRING-IN
       PERFORM MAKE-AND-SHOW
       MOVE '1234567890' TO STRING-IN
       PERFORM MAKE-AND-SHOW
       MOVE SPACES TO STRING-IN
       PERFORM MAKE-AND-SHOW
       STOP RUN
       .

   INITIALIZE-LENGTH.
       MOVE LENGTH OF STRING-IN TO STRING-LENGTH
       IF LENGTH OF STRING-OUT NOT = STRING-LENGTH
           DISPLAY 'LENGTH OF STRING-IN, ' STRING-LENGTH ', '
                   'NOT EQUAL TO LENGTH OF STRING-OUT, '
                   LENGTH OF STRING-OUT
           STOP RUN
       END-IF
       .

   MAKE-AND-SHOW.
       PERFORM MAKE-STRING-OUT
       PERFORM SHOW-BEFORE-AFTER
       .

   MAKE-STRING-OUT.
       MOVE ZEROS         TO STRING-OUT
       MOVE STRING-LENGTH TO CHAR-OUT-NUM
                             CHAR-IN-NUM
       PERFORM STRING-LENGTH TIMES
           IF STRING-IN (CHAR-IN-NUM:1) NOT = SPACE
               MOVE STRING-IN (CHAR-IN-NUM:1) 
                 TO STRING-OUT (CHAR-OUT-NUM:1)
               SUBTRACT 1 FROM CHAR-OUT-NUM
           END-IF
           SUBTRACT 1 FROM CHAR-IN-NUM
       END-PERFORM
       .

   SHOW-BEFORE-AFTER.
       DISPLAY "STRING IN:  '" STRING-IN "'"
       DISPLAY "STRING OUT: '" STRING-OUT "'"
       DISPLAY " "
       .


  **********************************************
  * EARLIER VERSION, BEFORE IMPROVEMENTS 
  * SUGGESTED IN COMMENTS
  **********************************************

   IDENTIFICATION DIVISION.
   PROGRAM-ID. SHIFT-LEFT.
  * SITUATION ON STACKOVERFLOW.COM:
  * I HAVE AN ALPHANUMERIC VARIABLE WITH A LENGTH OF 10. 
  * IT CONTAINS A NUMBER AT THE BEGINNING, THE REST OF THE DIGITS 
  * ARE FILLED WITH SPACES. THEN I NEED TO MOVE THE STRING TO THE 
  * LEFT AND PUT THE NUMBER OF SPACES WITH '0' AT THE BEGINING. 
  * THIS EXAMPLES SPEAKS FOR THEMSELVES:

  * INPUT            OUTPUT
  * ==============================
  * '123456    ' ->  '0000123456'
  * '12345678  ' ->  '0012345678'
  * '123456789 ' ->  '0123456789'
  * '1234567890' ->  '1234567890'
  *
  * ASSUME INPUT DATA VALIDATION DONE ELSEWHERE.


   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.

   DATA DIVISION.
   FILE SECTION.

   WORKING-STORAGE SECTION.
   01  STRING-IN                   PIC X(10).
   01  STRING-OUT                  PIC X(10).
   01  CHAR-IN-NUM                 PIC 99 USAGE COMP-3.
   01  CHAR-OUT-NUM                PIC 99 USAGE COMP-3.

   PROCEDURE DIVISION.
   MAIN.
       MOVE '123456    ' TO STRING-IN
       PERFORM MAKE-AND-SHOW
       MOVE '12345678  ' TO STRING-IN
       PERFORM MAKE-AND-SHOW
       MOVE '12345678  ' TO STRING-IN
       PERFORM MAKE-AND-SHOW
       MOVE '123456789 ' TO STRING-IN
       PERFORM MAKE-AND-SHOW
       MOVE '1234567890' TO STRING-IN
       PERFORM MAKE-AND-SHOW

       STOP RUN
       .

   MAKE-AND-SHOW.
       PERFORM MAKE-STRING-OUT
       PERFORM SHOW-BEFORE-AFTER
       .

   MAKE-STRING-OUT.
       MOVE SPACES TO STRING-OUT
       MOVE 10     TO CHAR-OUT-NUM
       PERFORM VARYING CHAR-IN-NUM FROM 10 BY -1
           UNTIL CHAR-IN-NUM < 1
           IF STRING-IN (CHAR-IN-NUM:1) NOT = SPACE
               MOVE STRING-IN (CHAR-IN-NUM:1) 
                 TO STRING-OUT (CHAR-OUT-NUM:1)
               SUBTRACT 1 FROM CHAR-OUT-NUM
           END-IF
       END-PERFORM
       PERFORM UNTIL CHAR-OUT-NUM < 1
           MOVE ZERO TO STRING-OUT (CHAR-OUT-NUM:1)
           SUBTRACT 1 FROM CHAR-OUT-NUM
       END-PERFORM
       .

   SHOW-BEFORE-AFTER.
       DISPLAY "STRING IN:  '" STRING-IN "'"
       DISPLAY "STRING OUT: '" STRING-OUT "'"
       DISPLAY " "
       .