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