COBOL数值变量非数值错误求助:无法累加销售数量至循环变量
解决COBOL中数值变量非数字错误及程序优化建议
问题描述
作为COBOL初学者,尝试将销售数量变量WS-CANTIDAD-VENTAS的值累加到数值变量WS-SUM-VENTAS,并以此作为PERFORM循环条件时触发错误:
"libcob: PROG-PAGOS-F.cbl: 57: 'WS-CANTIDAD-VENTAS' not numeric: '2 '
WARNING - Implicit CLOSE of REG-VENDEDORES ('REG-MAESTRO.DAT')"
程序停滞,以下是未完成代码及示例输入数据:
原程序代码
IDENTIFICATION DIVISION. PROGRAM-ID. PROG-PAGOS-F. AUTHOR. LUCAS GALEANO. DATE-WRITTEN. 1/2/2023. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT REG-VENDEDORES ASSIGN TO "REG-MAESTRO.DAT" ORGANIZATION IS LINE SEQUENTIAL. SELECT REG-VENTAS ASSIGN TO "REG-VENTAS-MAESTRO.DAT" ORGANIZATION IS LINE SEQUENTIAL. DATA DIVISION. FILE SECTION. FD REG-VENDEDORES. 01 VENDEDORES PIC 9(11). FD REG-VENTAS. 01 COBRO-VENTAS PIC 9(5). WORKING-STORAGE SECTION. 01 WS-VENDEDORES. 05 WS-EMPLEADO PIC 999. 05 WS-SUELDO-BASE PIC 9(5). 05 WS-CANTIDAD-VENTAS PIC 999. 77 WS-COBROS PIC 9(5). 77 WS-SUM-VENTAS PIC 99. 77 WS-CONTADOR PIC 99 VALUE ZEROS. 01 WS-TABLAS. 05 WS-REGISTRO-COBROS PIC 9(5) OCCURS 100 TIMES. PROCEDURE DIVISION. BEGIN-OUTPUT. OPEN OUTPUT REG-VENDEDORES. DISPLAY "INGRESE DATOS SOLICITADOS". PERFORM INGRESO-DATOS-EMPLEADOS. PERFORM UNTIL WS-VENDEDORES EQUALS SPACES WRITE VENDEDORES FROM WS-VENDEDORES PERFORM INGRESO-DATOS-EMPLEADOS END-PERFORM. DISPLAY "INGRESE COBROS DE CADA VENTA:". PERFORM INGRESO-VENTAS WITH TEST AFTER UNTIL WS-CONTADOR EQUALS WS-SUM-VENTAS MOVE WS-COBROS TO WS-REGISTRO-COBROS(1) CLOSE REG-VENDEDORES. STOP RUN. INGRESO-DATOS-EMPLEADOS. DISPLAY "EEE$$$$$VVV". ACCEPT WS-VENDEDORES. ADD WS-CANTIDAD-VENTAS TO WS-SUM-VENTAS. INGRESO-VENTAS. ADD 1 TO WS-CONTADOR. DISPLAY "$$$$$". ACCEPT WS-COBROS.
示例输入数据
INGRESE DATOS SOLICITADOS EEE$$$$$VVV 1 400002
问题原因分析
- 输入格式不匹配:
WS-VENDEDORES由3位员工号、5位基本工资、3位销售数量组成,总长度11位。但示例输入包含空格,导致WS-CANTIDAD-VENTAS被赋值为带空格的'2 ',COBOL执行ADD操作时要求操作数为纯数字,触发非数字错误。 - 循环逻辑缺陷:直接将组项
WS-VENDEDORES与空格比较不符合COBOL组项比较规则;且WS-SUM-VENTAS因非法输入值异常,导致后续PERFORM循环条件失效。 - 文件处理不规范:程序异常终止时未显式关闭
REG-VENDEDORES,触发隐式关闭警告。
解决方法
修正输入格式匹配
- 要求用户输入严格按照字段长度拼接,无空格,示例输入应改为
00140000002(3位员工号+5位基本工资+3位销售数量);或修改变量结构,添加空格分隔的解析逻辑。
- 要求用户输入严格按照字段长度拼接,无空格,示例输入应改为
增加输入合法性校验
在执行ADD操作前检查WS-CANTIDAD-VENTAS是否为纯数字,非法时重新输入:INGRESO-DATOS-EMPLEADOS. DISPLAY "请输入员工号(3位)+基本工资(5位)+销售数量(3位):". ACCEPT WS-VENDEDORES. IF WS-CANTIDAD-VENTAS IS NUMERIC ADD WS-CANTIDAD-VENTAS TO WS-SUM-VENTAS ELSE DISPLAY "错误:销售数量输入非法,请重新输入" PERFORM INGRESO-DATOS-EMPLEADOS END-IF.修复循环逻辑
- 将组项比较改为判断具体字段,比如用员工号是否为0作为终止条件:
PERFORM UNTIL WS-EMPLEADO EQUALS ZEROS。 - 确保
WS-SUM-VENTAS初始化为0,避免初始值异常:77 WS-SUM-VENTAS PIC 99 VALUE ZEROS.
- 将组项比较改为判断具体字段,比如用员工号是否为0作为终止条件:
规范文件操作
在程序所有退出路径(包括错误分支)显式关闭文件,避免隐式关闭警告。
代码优化建议
- 命名可读性提升:使用更清晰的命名,比如
WS-EMPLEADO改为WS-EMPLOYEE-ID,WS-SUELDO-BASE改为WS-BASE-SALARY,增强代码可维护性。 - 变量长度合理性调整:
WS-SUM-VENTAS定义为PIC 99最多只能累加99,若销售数量总和可能超过两位,应调整为PIC 9(4)等更大长度。 - 数组正确使用:当前代码仅给数组下标1赋值,应使用
WS-CONTADOR作为下标存储多笔销售记录:MOVE WS-COBROS TO WS-REGISTRO-COBROS(WS-CONTADOR)。 - 输入提示优化:将模糊的提示改为明确引导,帮助用户正确输入。
- 错误处理模块化:新增错误处理段落,统一处理输入非法、文件操作失败等异常情况,避免程序直接崩溃。
修正后示例代码
IDENTIFICATION DIVISION. PROGRAM-ID. PROG-PAGOS-F. AUTHOR. LUCAS GALEANO. DATE-WRITTEN. 1/2/2023. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT REG-VENDEDORES ASSIGN TO "REG-MAESTRO.DAT" ORGANIZATION IS LINE SEQUENTIAL. SELECT REG-VENTAS ASSIGN TO "REG-VENTAS-MAESTRO.DAT" ORGANIZATION IS LINE SEQUENTIAL. DATA DIVISION. FILE SECTION. FD REG-VENDEDORES. 01 VENDEDORES PIC 9(11). FD REG-VENTAS. 01 COBRO-VENTAS PIC 9(5). WORKING-STORAGE SECTION. 01 WS-VENDEDORES. 05 WS-EMPLOYEE-ID PIC 999. 05 WS-BASE-SALARY PIC 9(5). 05 WS-SALE-COUNT PIC 999. 77 WS-SALE-AMOUNT PIC 9(5). 77 WS-TOTAL-SALES PIC 9(4) VALUE ZEROS. 77 WS-COUNTER PIC 99 VALUE ZEROS. 01 WS-SALE-RECORDS. 05 WS-RECORD-AMOUNT PIC 9(5) OCCURS 100 TIMES. PROCEDURE DIVISION. MAIN-PROCEDURE. OPEN OUTPUT REG-VENDEDORES. DISPLAY "=== 输入员工数据 ===". PERFORM INPUT-EMPLOYEE-DATA. PERFORM UNTIL WS-EMPLOYEE-ID EQUALS ZEROS WRITE VENDEDORES FROM WS-VENDEDORES PERFORM INPUT-EMPLOYEE-DATA END-PERFORM. IF WS-TOTAL-SALES > 0 DISPLAY "=== 输入每笔销售金额 ===". PERFORM INPUT-SALE-DATA WITH TEST AFTER UNTIL WS-COUNTER EQUALS WS-TOTAL-SALES MOVE WS-SALE-AMOUNT TO WS-RECORD-AMOUNT(WS-COUNTER) END-PERFORM ELSE DISPLAY "无销售记录需要输入" END-IF. CLOSE REG-VENDEDORES. STOP RUN. INPUT-EMPLOYEE-DATA. DISPLAY "请输入:员工号(3位)+基本工资(5位)+销售数量(3位)(输入00000000000结束):". ACCEPT WS-VENDEDORES. IF WS-EMPLOYEE-ID NOT EQUALS ZEROS IF WS-SALE-COUNT IS NUMERIC ADD WS-SALE-COUNT TO WS-TOTAL-SALES ELSE DISPLAY "错误:销售数量必须为数字,请重新输入" PERFORM INPUT-EMPLOYEE-DATA END-IF END-IF. INPUT-SALE-DATA. ADD 1 TO WS-COUNTER. DISPLAY "请输入第" WS-COUNTER "笔销售金额:". ACCEPT WS-SALE-AMOUNT.
内容的提问来源于stack exchange,提问作者Lucas Galeano
相关产品推荐
相关产品推荐

