On m’a soumis récément un problème qui me semblait simple mais ne l’était pas tant que ça :

Dans un programme COBOL, comment concaténer un nom en PIC X(32) et un prénom en PIC X(32) dans un champ résultant en PIC X(32), sachant que le nom ou le prénom peuvent être composés d’1 ou plusieurs mots séparés par un espace et qu’en cas de troncature dans le champ résultant le nom prime.

Bouaaahhh! Facile! Avec une boucle lettre par lettre est un INSPECT qui va bien on doit pouvoir faire ça rapidos.

Je me suis amusé et bien c’etait pas jojo à voir!

C’est Homer-ac sur ce billet du forum Cobol de DVP qui m’a donné la piste du code final que voilà :

       
WORKING-STORAGE SECTION.
01 W-CPT           PIC S9(4) COMP.
01 W-LONG-NOM      PIC S9(4) COMP.
01 W-NOM           PIC X(32).
01 W-NOM-REV       PIC X(32).
01 W-PRENOM        PIC X(32).
01 W-NOMPREN       PIC X(32).
 
PROCEDURE DIVISION.
 
INITIALIZE W-NOM W-NOM-REV W-PRENOM W-NOMPREN.
 
IF W-NOM NOT = SPACE
  MOVE FUNCTION REVERSE(W-NOM) TO W-NOM-REV
  MOVE 0 TO W-CPT
  INSPECT W-NOM-REV TALLYING W-CPT FOR LEADING
    SPACE
  SUBTRACT W-CPT FROM LENGTH OF W-NOM-REV GIVING
    W-LONG-NOM
END-IF.
 
STRING W-NOM(1:W-LONG-NOM) SPACE W-PRENOM
  DELIMITED BY SIZE INTO W-NOMPREN
END-STRING.

La fonction REVERSE permet d’inverser l’ordre de la donnée, les blancs de fin passent alors en première position, l’INSPECT TALLYING compte le nombre d’espace consécutif en début de chaîne, nombre qu’il suffit de soustraire à la longueur de la picture “nom” pour obtenir la position du premier espace à la fin de ce nom. Il suffit ensuite de concaténer nom et prénom avec STRING sans omettre d’indiquer la “portion” de nom qui doit être concaténer.