Explorar temas

INFORMÁTICA

10 ejemplos de COBOL con código y resultados

Mostrar un mensaje, calcular un importe y leer un archivo son buenas formas de empezar con COBOL. Los diez programas siguientes se pueden guardar, compilar y ejecutar por separado; cada uno incluye su salida y una explicación de lo que conviene observar.

COBOL significa Common Business-Oriented Language, lenguaje común orientado a los negocios. Se utiliza en procesamiento de datos administrativos, como nóminas, contabilidad y sistemas financieros. Sus instrucciones se parecen a palabras del inglés, pero tienen una sintaxis precisa. [4]

Cómo ejecutar los ejemplos

Se han compilado y ejecutado con GnuCOBOL 3.2.0, dialecto predeterminado (-std=default) y formato libre (-free), en Windows. Usa una terminal donde el compilador esté configurado; cobc --version permite comprobarlo. El programa no exige un mainframe. [1] [2]

Guarda el primer código como saludo.cob. En Windows, compila y ejecuta:

cobc -x -free -std=default -o saludo.exe saludo.cob
.\saludo.exe

En una terminal de Linux o macOS con GnuCOBOL disponible:

cobc -x -free -std=default -o saludo saludo.cob
./saludo

Para los demás, cambia saludo por el nombre que aparece en cada ejemplo. -x crea un ejecutable y -free evita interpretar el código con las columnas del formato fijo. Las salidas usan texto sin tildes para simplificar las diferencias de codificación entre consolas; el punto decimal se mantiene en todos los programas.

Descargar los diez programas y pedidos.txt. El archivo incluye instrucciones y resultados esperados; no incluye compilador ni ejecutables. La sección de CICS se explica aparte y no forma parte de este conjunto ejecutado.

10 ejemplos de COBOL para practicar

Los códigos son programas completos e independientes. Comienza por los primeros y avanza hasta la lectura de archivos: cada ejemplo incorpora una operación o un caso de error distinto. En móvil puedes desplazar el código horizontalmente; con teclado, enfoca el bloque y usa las flechas.

EJEMPLO 01 · DISPLAY y programa mínimo

Mostrar un mensaje

Archivo: saludo.cob

identification division.
program-id. saludo.
procedure division.
    display "Programa de ejemplo de Cobol"
    stop run.

Descargar saludo.cob

Salida

Programa de ejemplo de Cobol

DISPLAY escribe el texto entre comillas rectas. STOP RUN termina este programa principal. No hacen falta declaraciones de datos para mostrar un literal.

Las divisiones ENVIRONMENT y DATA pueden omitirse aquí porque no hay configuración externa ni datos que declarar.

EJEMPLO 02 · PIC X, PIC 9, MOVE y espacios

Declarar y mostrar datos

Archivo: ficha.cob

identification division.
program-id. ficha.
data division.
working-storage section.
01 nombre pic x(12) value "Ana".
01 unidades pic 9(3) value 7.
procedure division.
    move "Luis" to nombre
    display "Nombre: " function trim(nombre)
    display "Unidades: " unidades
    stop run.

Descargar ficha.cob

Salida

Nombre: Luis
Unidades: 007

El campo alfanumérico admite doce posiciones; MOVE cambia su contenido y lo completa con espacios. TRIM permite mostrar el nombre sin los espacios finales. El campo numérico tiene tres dígitos, por eso se ven los ceros iniciales.

EJEMPLO 03 · Decimales implícitos y formato de salida

Comparar truncamiento y redondeo

Archivo: decimales.cob

identification division.
program-id. decimales.
data division.
working-storage section.
01 importe pic 99v999 value 19.995.
01 corto pic 99v99.
01 redondo pic 99v99.
01 salida pic 99.99.
procedure division.
    compute corto = importe
    compute redondo rounded = importe
    move corto to salida
    display "Sin redondeo: " salida
    move redondo to salida
    display "Con redondeo: " salida
    stop run.

Descargar decimales.cob

Salida

Sin redondeo: 19.99
Con redondeo: 20.00

V indica una posición decimal implícita: no es un carácter almacenado. Al reducir de tres a dos decimales, COMPUTE sin ROUNDED trunca; con ROUNDED redondea. La máscara editada 99.99 hace visible el punto. Estos programas usan punto decimal y datos positivos definidos en el código.

La capacidad del campo importa: un redondeo también puede producir un valor que ya no quepa. La regla de redondeo apropiada para un sistema real debe definirse en sus requisitos.

EJEMPLO 04 · ON SIZE ERROR y estado conservado

Detectar un resultado que no cabe

Archivo: limite.cob

identification division.
program-id. limite.
data division.
working-storage section.
01 contador pic 99 value 98.
procedure division.
    perform 2 times
        add 1 to contador
            on size error display "No cabe"
            not on size error display "Correcto"
        end-add
        display "Contador: " contador
    end-perform
    stop run.

Descargar limite.cob

Salida

Correcto
Contador: 99
No cabe
Contador: 99

El primer incremento cabe en dos dígitos. El segundo intentaría guardar 100 y ejecuta ON SIZE ERROR. En esa operación, el receptor conserva 99. La comprobación evita tratar un resultado recortado como si fuera correcto.

El tratamiento de errores de tamaño evita aceptar silenciosamente el resultado de una operación que no cabe. [5]

EJEMPLO 05 · EVALUATE y WHEN OTHER

Elegir entre varios estados

Archivo: estado.cob

Entrada de esta ejecución: escribe C y pulsa Intro. La salida de abajo muestra lo que escribe el programa, sin incluir el eco del teclado.

identification division.
program-id. estado.
data division.
working-storage section.
01 codigo pic x.
procedure division.
    accept codigo
    evaluate codigo
        when "P" display "Pendiente"
        when "C" display "Confirmado"
        when "A" display "Anulado"
        when other display "Codigo desconocido"
    end-evaluate
    stop run.

Descargar estado.cob

Salida

Confirmado

EVALUATE selecciona una rama según el código introducido. WHEN OTHER cubre los valores que no coinciden. Las comparaciones distinguen mayúsculas y minúsculas: c no equivale a C.

Escribe un solo carácter y pulsa Intro; el campo de este ejemplo tiene una posición.

EJEMPLO 06 · PERFORM VARYING

Sumar con un bucle

Archivo: suma.cob

identification division.
program-id. suma.
data division.
working-storage section.
01 indice pic 9.
01 total pic 99 value 0.
procedure division.
    perform varying indice from 1 by 1
        until indice > 5
        add indice to total
    end-perform
    display "Total: " total
    stop run.

Descargar suma.cob

Salida

Total: 15

El bucle suma 1 + 2 + 3 + 4 + 5. Comprueba la condición antes de cada vuelta; cuando el índice alcanza 6, termina. El receptor de dos dígitos basta para estos datos, pero no para cualquier suma.

EJEMPLO 07 · OCCURS, subíndices e IF

Recorrer una tabla de importes

Archivo: tabla.cob

identification division.
program-id. tabla.
data division.
working-storage section.
01 ventas.
   05 importe pic 9(3) occurs 3 times.
01 indice pic 9.
01 total pic 9(4) value 0.
01 mayores pic 9 value 0.
procedure division.
    move 120 to importe(1)
    move 80 to importe(2)
    move 150 to importe(3)
    perform varying indice from 1 by 1
        until indice > 3
        add importe(indice) to total
        if importe(indice) > 100
            add 1 to mayores
        end-if
    end-perform
    display "Total: " total
    display "Mayores de 100: " mayores
    stop run.

Descargar tabla.cob

Salida

Total: 0350
Mayores de 100: 2

OCCURS reserva tres elementos con la misma descripción. Sus subíndices son 1, 2 y 3. El programa acumula todos los importes y cuenta solo los que superan 100; un importe igual a 100 no cumple la condición.

EJEMPLO 08 · STRING y ON OVERFLOW

Unir textos con un separador

Archivo: nombre.cob

identification division.
program-id. nombre.
data division.
working-storage section.
01 nombre pic x(10) value "Ana".
01 apellido pic x(10) value "Luna".
01 completo pic x(25) value spaces.
01 cabe pic 9 value 1.
procedure division.
    string function trim(nombre) " "
        function trim(apellido)
        delimited by size into completo
        on overflow move 0 to cabe
    end-string
    if cabe = 1
        display function trim(completo)
    else
        display "Texto demasiado largo"
    end-if
    stop run.

Descargar nombre.cob

Salida

Ana Luna

STRING concatena nombre, un espacio y apellido. DELIMITED BY SIZE utiliza el tamaño de cada elemento enviado; TRIM quita el relleno de los campos. ON OVERFLOW detecta que el destino no basta, y el programa evita mostrar el resultado parcial.

ON OVERFLOW no promete deshacer lo ya copiado. Por eso este ejemplo usa una bandera y no presenta el campo como resultado completo cuando falla.

EJEMPLO 09 · ACCEPT, prueba NUMERIC y NUMVAL

Validar un entero antes de convertirlo

Archivo: entrada.cob

Entrada de esta ejecución: escribe 12 y pulsa Intro. La salida de abajo muestra lo que escribe el programa, sin incluir el eco del teclado.

identification division.
program-id. entrada.
data division.
working-storage section.
01 entrada pic x(80).
01 cantidad pic 99.
procedure division.
    accept entrada
    if function length(function trim(entrada)) = 2
        if function trim(entrada) is numeric
            compute cantidad = function numval(entrada)
            display "Cantidad: " cantidad
        else
            display "Escribe exactamente dos digitos"
        end-if
    else
        display "Escribe exactamente dos digitos"
    end-if
    stop run.

Descargar entrada.cob

Salida

Cantidad: 12

Se recibe texto y se comprueba que, tras quitar espacios exteriores, contiene exactamente dos dígitos. Solo entonces se convierte. Acepta 00 a 99; rechaza 7, -1, 1.5, letras y una entrada vacía. Una regla que exigiera una cantidad positiva tendría que comprobar además que el valor es mayor que cero.

La entrada se limita a 80 caracteres en este ejercicio de consola; ACCEPT no constituye por sí solo un validador general de entradas de longitud arbitraria.

EJEMPLO 10 · FILE STATUS y fin de archivo

Leer un archivo línea por línea

Archivo: lectura.cob

Contenido de pedidos.txt:

Pedido A
Pedido B
Pedido C

Descargar pedidos.txt

identification division.
program-id. lectura.
environment division.
input-output section.
file-control.
    select pedidos assign to "pedidos.txt"
        organization is line sequential
        file status is estado-archivo.
data division.
file section.
fd pedidos.
01 registro pic x(80).
working-storage section.
01 estado-archivo pic xx.
01 fin pic 9 value 0.
01 total pic 9(4) value 0.
procedure division.
    open input pedidos
    if estado-archivo not = "00"
        display "No se pudo abrir: " estado-archivo
        stop run
    end-if
    perform until fin = 1
        read pedidos
        evaluate estado-archivo
            when "00"
                display function trim(registro)
                add 1 to total
                    on size error
                        display "Demasiados registros"
                        move 1 to fin
                end-add
            when "10" move 1 to fin
            when other
                display "Error de lectura: " estado-archivo
                move 1 to fin
        end-evaluate
    end-perform
    close pedidos
    if estado-archivo not = "00"
        display "Error de cierre: " estado-archivo
    end-if
    display "Registros contados: " total
    stop run.

Descargar lectura.cob

Salida

Pedido A
Pedido B
Pedido C
Registros contados: 0003

Guarda pedidos.txt en la carpeta desde la que ejecutas el programa. OPEN INPUT abre para lectura; el código 00 indica éxito y 10, fin de archivo. El bucle solo cuenta registros leídos correctamente. CLOSE libera el archivo. Si no se puede abrir, el programa informa del estado y termina.

Usa líneas de hasta 80 caracteres y un máximo de 9.999 registros en este ejercicio. Un archivo vacío produce 0000. Una línea vacía es un registro y también se cuenta. El total es el número contado, no una confirmación de que nunca hubo errores.

Divisiones y tipos de datos en COBOL

Dónde se describe cada parte del programa
DivisiónFunciónEjemplo
IDENTIFICATIONIdentifica el programa.PROGRAM-ID. saludo.
ENVIRONMENTConfigura relaciones con el entorno, como archivos.SELECT pedidos ASSIGN TO "pedidos.txt".
DATADeclara registros y campos.WORKING-STORAGE SECTION.
PROCEDUREContiene las instrucciones ejecutables.DISPLAY, COMPUTE, IF y PERFORM.

PIC X(12) describe doce posiciones alfanuméricas; PIC 9(3), tres dígitos; PIC 99V99, dos enteros y dos decimales implícitos. Para valores negativos hace falta un formato con signo adecuado; los ejemplos numéricos de esta página trabajan con cantidades no negativas.

Usa cierres explícitos como END-IF y END-PERFORM. Un punto termina una sentencia COBOL y puede cerrar ámbitos aún abiertos: no lo añadas al final de cada línea por costumbre de otros lenguajes. La indentación ayuda a leer, pero no sustituye esos límites. [3]

COBOL con CICS: enviar una pantalla

CICS es un entorno de procesamiento de transacciones. Las instrucciones EXEC CICS … END-EXEC son servicios de ese entorno, no instrucciones de consola equivalentes a DISPLAY. Un mapa BMS describe una pantalla y pertenece a un conjunto de mapas o mapset. [6]

Fragmento contextual para IBM CICS TS; no ejecutado aquí. Supone un programa CICS ya configurado, con el mapa INICIO en el mapset DEMOMAP disponibles. No es un programa autónomo para compilar con los comandos anteriores.

*> Fragmento para un programa de IBM CICS TS.
*> Requiere el mapa INICIO en el mapset DEMOMAP.
exec cics send map('INICIO') mapset('DEMOMAP')
    maponly erase
    resp(ws-resp) resp2(ws-resp2)
end-exec
if ws-resp not = dfhresp(NORMAL)
    perform tratar-error
end-if
exec cics return
end-exec

ws-resp y ws-resp2 deben declararse en WORKING-STORAGE como campos binarios de palabra completa, por ejemplo cada uno con PIC S9(8) COMP. tratar-error representa un párrafo que la aplicación debe implementar para atender una respuesta no normal; no está definido en este fragmento. Se necesita además el procesamiento de CICS para traducir sus comandos.

El contenido visible de la pantalla lo determina el mapa definido en el entorno; sin ese recurso no se puede prometer una salida concreta. [7] [8] [9]

Usos, historia y compiladores

COBOL nació del trabajo de CODASYL iniciado en 1959 para facilitar el procesamiento de datos de negocio. Puede participar en procesos por lotes, como calcular una nómina, o en aplicaciones transaccionales. Conservar un sistema también depende de sus reglas de negocio, integraciones y requisitos; no se explica solo por el costo de cambiar de lenguaje. [4]

COBOL 85 reforzó la programación estructurada, por ejemplo con terminadores explícitos de ámbito. No hay que atribuirle en bloque todas las capacidades de compiladores posteriores: recursividad, almacenamiento local y gestión dinámica de memoria deben comprobarse en el estándar y el compilador concretos. [3]

El lenguaje y el compilador son cosas diferentes. GnuCOBOL permite practicar en equipos personales; IBM mantiene compiladores para sus plataformas. Los entornos mainframe son un ámbito de uso, no un requisito para ejecutar todo programa COBOL. [1] [4]

Microsoft COBOL aparece en la historia de productos de Microsoft de 1980. RM/COBOL 11 también es una versión histórica, anterior a RM/COBOL 12 en la documentación de migración. Esas denominaciones no deben confundirse con un catálogo de versiones actuales. [10] [11]

8 ejercicios para practicar

  1. ¿Por qué el ejemplo 2 muestra 007 y no 7?
  2. ¿Qué representa V en PIC 99V99?
  3. ¿Qué salidas da el ejemplo 3 con 19.994?
  4. ¿Por qué el contador del ejemplo 4 sigue en 99 al fallar?
  5. ¿Qué muestra el ejemplo 5 si introduces X o c?
  6. Si el importe central de la tabla pasa de 80 a 100, ¿qué cambia?
  7. ¿Acepta el ejemplo 9 las entradas 00, 7 y AB?
  8. ¿Da lo mismo un archivo vacío que uno inexistente?
Ver respuestas razonadas
  1. El receptor PIC 9(3) tiene tres posiciones numéricas; DISPLAY muestra sus ceros iniciales.
  2. La posición decimal implícita. Para mostrar un punto se mueve el valor a una máscara editada, como 99.99.
  3. Sin redondeo: 19.99. Con redondeo: 19.99. Con 19.995, en cambio, ROUNDED da 20.00.
  4. La operación detecta SIZE ERROR y, al manejarlo con ON SIZE ERROR, conserva el receptor de esa operación.
  5. Codigo desconocido en ambos casos: no coinciden con P, C ni A.
  6. El total pasa de 0350 a 0370. El contador de mayores de 100 sigue en 2 porque 100 no es mayor que 100.
  7. Acepta 00. Rechaza 7 porque tiene un solo dígito y AB porque no es numérico.
  8. No. El vacío se abre y alcanza el fin sin registros; el inexistente falla al abrirse. En el entorno probado, el estado de archivo inexistente es 35.

Errores frecuentes

Referencias

  1. [1] GnuCOBOL · Proyecto y plataformas
  2. [2] GnuCOBOL · Manual: compilación y formatos
  3. [3] GnuCOBOL · Guía del programador: datos e instrucciones
  4. [4] IBM · Qué es COBOL
  5. [5] IBM · Asignación de resultados y SIZE ERROR
  6. [6] IBM · Uso de SEND MAP
  7. [7] IBM · Combinación de mapas físicos y simbólicos
  8. [8] IBM · EXEC CICS SEND MAP
  9. [9] IBM · EXEC CICS RETURN
  10. [10] Microsoft · Historia de Microsoft: 1980
  11. [11] Micro Focus · Migración: RM/COBOL 11 y 12