我有一个长度为10的字母数字变量。它在开头包含一个数字,其余数字用空格填充。然后我需要将字符串向左移动并在开头放置'0'的空格数。这个例子说明了一切:
INPUT OUTPUT
==============================
'123456 ' -> '0000123456'
'12345678 ' -> '0012345678'
'123456789 ' -> '0123456789'
'1234567890' -> '1234567890'
然后我做了类似的事情:
检查此COBOL小提琴,您可以尝试: http://ideone.com/mgbKZ3 (只需点击编辑)
IDENTIFICATION DIVISION.
PROGRAM-ID. VARSWAP.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 VARIN PIC X(10).
01 VARSWAP PIC X(10) JUSTIFIED RIGHT.
PROCEDURE DIVISION.
MOVE '123456 ' TO VARIN
UNSTRING VARIN DELIMITED BY ' ' INTO VARSWAP
INSPECT VARSWAP REPLACING LEADING SPACE BY '0'
MOVE VARSWAP TO VARIN
DISPLAY VARIN
STOP RUN.
返回:
0000123456
似乎工作正常,但我想知道你是否有更好,更简单或更清晰的方法。
答案 0 :(得分:8)
您应该使用所有空白的输入来测试您的代码。
如果您 绝对 某些数据质量,无论是否检查空白,您都可以这样做:
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
.
我不喜欢破坏输入,所以我改变了。
一种流行的方法是,FUNCTION REVERSE(你的领域),然后是INSPECT反向领域TALLYING ......用于领先空间。您可以在程序的早期使用FUNCTION LENGTH来确定字段的长度(并确保它们的长度相同)然后,首先将VARIN设置为ZERO,对源和目标使用引用修改 - 源将是( 1:计算的数据长度)目标将是(计算 - 右对齐开始:)(未指定长度使用字段的剩余部分)。
还有可变长度字段,逐字节MOVE(有时候是“传统主义者”首选,但最不清楚的是)。
具体方法取决于您的数据。如果您需要验证数据,首先需要代码,这将使您更清楚地选择。如果您的数据有保证,干净,那么......
我知道这只是一个例子,但我希望你能使用更好的数据名称。
答案 1 :(得分:2)
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 " "
.
答案 2 :(得分:1)
如果你有内在函数,请将一个功能修剪,LEADING或TRAILING作为适合目的,通过图9中的TRAILING,或者在下面的例子中同时进行。
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上面提到的验证,这假设所有空格都相当于0.这可能是也可能不是一个理智的东西。非数字也是一个问题。
答案 3 :(得分:1)
最简单的方法是在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.
答案 4 :(得分:1)
我很惊讶没有人建议在这里使用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
.
产生......
>123456 <
>0000123456<
这种方法的问题是如果NUMVAL
参数没有转换为
数字程序引发异常并死亡。这也不是很好
从CPU使用的角度来看是有效的,因为它需要字符
二进制数字转换并再次返回显示格式(全部在封面下完成但需要循环)。
作为一般规则,我不会 建议使用NUMVAL(即使它看起来像'更好'的解决方案)。我会坚持使用解决方案 正如原始问题中所述。那 解决方案在计算上是高效的,并且是COOBL编程中常用的习惯用法。