J'ai besoin d'aide pour mes devoirs de COBOL.

désolé de vous déranger, mais je suis coincé dans mes devoirs pour COBOL. J'ai fait deux tentatives, aucune ne marche comme prévu.

les deux essais et leurs résultats sont présentés ci-dessous, suivis des résultats finaux qu'ils doivent être. Je vous remercie tous pour votre aide.

Première tentative:

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIL-LABEL.
*
******************************************************************
* This program prints duplicate side by side mailing labels.
******************************************************************
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.

SELECT LABEL-FILE-IN
ASSIGN TO 'MAIL-LABEL.SEQ'
ORGANIZATION IS LINE SEQUENTIAL.

SELECT LABEL-FILE-OUT
ASSIGN TO 'MAIL-LABEL.RPT'
ORGANIZATION IS LINE SEQUENTIAL.

DATA DIVISION.
FILE SECTION.

FD LABEL-FILE-IN.
01 LABEL-RECORD-IN.
05 NAME-IN PIC X(20).
05 ADDRESS-IN PIC X(20).
05 CITY-STATE-ZIP-IN PIC X(20).

FD LABEL-FILE-OUT.
01 LABEL-RECORD-OUT.
05 LEFT-LABEL-OUT PIC X(20).
05 BLANK-OUT PIC X(15).
05 RIGHT-LABEL-OUT PIC X(20).
05 BLANK-A-OUT PIC X(5).

WORKING-STORAGE SECTION.
01 ARE-THERE-MORE-RECORDS PIC X(3) VALUE 'YES'.

PROCEDURE DIVISION.
100-MAIN.
OPEN INPUT LABEL-FILE-IN
OPEN OUTPUT LABEL-FILE-OUT

PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO'
READ LABEL-FILE-IN
AT END
MOVE 'NO' TO ARE-THERE-MORE-RECORDS
NOT AT END
PERFORM 200-PROCESS-ONE-RECORD
END-READ
END-PERFORM

CLOSE LABEL-FILE-IN
CLOSE LABEL-FILE-OUT
STOP RUN.

200-PROCESS-ONE-RECORD.
MOVE NAME-IN TO LEFT-LABEL-OUT
MOVE ADDRESS-IN TO BLANK-OUT
MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT
MOVE SPACES TO BLANK-A-OUT
WRITE LABEL-RECORD-OUT.

cela produit:

*IAN HENDERSON       1309 SPRINGBANKDETROIT     MI 48024
*JANET LEASA         12700 GRATIOT SWARREN      MI 48077
*COREY HAYES         400 BRUSH ST.  DETROIT     MI 48024
*SCOTT TOKLEY        2003 INDIAN RD.TAYLOR      MI 48075
*JUDY FISHER         2200 WOODWARD ADETROIT     MI 48025
*SHAWN MITCHELL      510 HOLLYWOOD PDETROIT     MI 48025
*MARCUS PILLON       1450 JOY RD    DEARBORN    MI 48077
*BRIAN GUENETTE      456 TRUMBULL STDETROIT     MI 48024
*KIM MIKA            456 LAFAYETTE SDETROIT     MI 48024
*KYLE THOMPSON       1617 MAPLE RD. WARREN      MI 48056
*SUE DONALDSON       11 CASS AVE.   DETROIT     MI 48024

Ma deuxième tentative:

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIL-LABEL.
*
******************************************************************
* This program prints duplicate side by side mailing labels.
******************************************************************
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.

SELECT LABEL-FILE-IN
ASSIGN TO 'MAIL-LABEL.SEQ'
ORGANIZATION IS LINE SEQUENTIAL.

SELECT LABEL-FILE-OUT
ASSIGN TO 'MAIL-LABEL.RPT'
ORGANIZATION IS LINE SEQUENTIAL.

DATA DIVISION.
FILE SECTION.

FD LABEL-FILE-IN.
01 LABEL-RECORD-IN.
05 NAME-IN PIC X(20).
05 ADDRESS-IN PIC X(20).
05 CITY-STATE-ZIP-IN PIC X(20).

FD LABEL-FILE-OUT.
01 LABEL-RECORD-OUT.
05 LEFT-LABEL-OUT PIC X(20).
05 BLANK-OUT PIC X(15).
05 RIGHT-LABEL-OUT PIC X(20).
05 BLANK-A-OUT PIC X(5).

WORKING-STORAGE SECTION.
01 ARE-THERE-MORE-RECORDS PIC X(3) VALUE 'YES'.

PROCEDURE DIVISION.
100-MAIN.
OPEN INPUT LABEL-FILE-IN
OPEN OUTPUT LABEL-FILE-OUT

PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO'
READ LABEL-FILE-IN
AT END
MOVE 'NO' TO ARE-THERE-MORE-RECORDS
NOT AT END
PERFORM 200-PROCESS-ONE-RECORD
END-READ
END-PERFORM

CLOSE LABEL-FILE-IN
CLOSE LABEL-FILE-OUT
STOP RUN.

200-PROCESS-ONE-RECORD.
MOVE NAME-IN TO LEFT-LABEL-OUT
MOVE ADDRESS-IN TO LEFT-LABEL-OUT
MOVE CITY-STATE-ZIP-IN TO LEFT-LABEL-OUT
MOVE SPACES TO BLANK-OUT
MOVE NAME-IN TO RIGHT-LABEL-OUT
MOVE ADDRESS-IN TO RIGHT-LABEL-OUT
MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT
MOVE SPACES TO BLANK-A-OUT
WRITE LABEL-RECORD-OUT

produit:

*DETROIT     MI 48024               DETROIT     MI 48024
*WARREN      MI 48077               WARREN      MI 48077
*DETROIT     MI 48024               DETROIT     MI 48024
*TAYLOR      MI 48075               TAYLOR      MI 48075
*DETROIT     MI 48025               DETROIT     MI 48025
*DETROIT     MI 48025               DETROIT     MI 48025
*DEARBORN    MI 48077               DEARBORN    MI 48077
*DETROIT     MI 48024               DETROIT     MI 48024
*DETROIT     MI 48024               DETROIT     MI 48024
*WARREN      MI 48056               WARREN      MI 48056
*DETROIT     MI 48024               DETROIT     MI 48024

Ce Que J' besoin à la fin, c'est quelque chose comme:

*IAN HENDERSON                      IAN HENDERSON 
*1309 SPRINGBANK ST.                1309 SPRINGBANK ST.
*DETROIT     MI 48024               DETROIT     MI 48024

*JANET LEASA                        JANET LEASA 
*12700 GRATIOT ST.                  12700 GRATIOT ST. 
*WARREN      MI 48077               WARREN      MI 48077

*COREY HAYES                        COREY HAYES
*400 BRUSH ST.                      400 BRUSH ST.
*DETROIT     MI 48024               DETROIT     MI 48024

*SCOTT TOKLEY                       SCOTT TOKLEY 
*2003 INDIAN RD.                    2003 INDIAN RD.
*TAYLOR      MI 48075               TAYLOR      MI 48075

Qu'est-ce qui ne va pas avec mon code?

14
demandé sur Bill the Lizard 2010-10-21 09:02:51

3 réponses

je pense que votre deuxième tentative était presque correct. Comme Paxdiablo l'a souligné dans sa réponse, le problème que vous avez est d'écraser les données.

si je comprends votre problème correctement, vous lisez dans un seul enregistrement contenant une adresse complète (Nom, Adresse, Ville-État-Zip) et doivent imprimez deux copies côte à côte.

notez que pour chaque ligne que vous lisez, vous devez imprimer 3. Notez également que vous seulement avoir un enregistrement de sortie de la mémoire tampon. Cela signifie que vous ne pouvez traiter une ligne de sortie à un temps. La solution est de déplacer chaque élément d'adresse dans la gauche et la droite de la ligne ouput, sortir la ligne et ensuite passer à la composante d'adresse suivante. Depuis il y a 3 composants d'adresse, vous finissez par Imprimer 3 lignes pour chaque lecture.

essayer de modifier le paragraphe 200-PROCESS-ONE-RECORD comme suit

200-PROCESS-ONE-RECORD. 
MOVE NAME-IN TO LEFT-LABEL-OUT
MOVE SPACES TO BLANK-OUT
MOVE NAME-IN TO RIGHT-LABEL-OUT
MOVE SPACES TO BLANK-A-OUT 
WRITE LABEL-RECORD-OUT

MOVE ADDRESS-IN TO LEFT-LABEL-OUT
MOVE SPACES TO BLANK-OUT
MOVE ADDRESS-IN TO RIGHT-LABEL-OUT
MOVE SPACES TO BLANK-A-OUT 
WRITE LABEL-RECORD-OUT 

MOVE CITY-STATE-ZIP-IN TO LEFT-LABEL-OUT
MOVE SPACES TO BLANK-OUT 
MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT 
MOVE SPACES TO BLANK-A-OUT 
WRITE LABEL-RECORD-OUT 

cela prend une ligne d'entrée, Produit 3 lignes de sortie. Vous pourriez sortie une quatrième ligne vide pour séparer adresses (comme illustré dans votre exemple de sortie-je vais laissez-vous comprendre comment faire).

je pense que la solution de Paxdiablo a résolu un problème légèrement différent où vous imprimeriez une copie de chaque adresse mais imprimeriez les adresses 2 à l'horizontale.

BTW... Malgré le nombre de commentaires désobligeants "drive by" votre question a obtenu, COBOL est toujours activement utilisé dans certains segments de cette industrie.

3
répondu NealB 2010-10-21 14:11:53

normalement, Je ne donnerais pas autant d'aide pour les devoirs, mais puisque vous y avez déjà mis pas mal d'efforts et qu'il est peu probable que vous trouviez beaucoup de dinosaures ici, je vais vous aider.

Ton problème est ici (ignorer les choses, entre parenthèses, sur la droite, ils sont juste des commentaires pour vous aider):

200-PROCESS-ONE-RECORD.
    MOVE NAME-IN TO LEFT-LABEL-OUT
    MOVE ADDRESS-IN TO LEFT-LABEL-OUT                (overwrite)
    MOVE CITY-STATE-ZIP-IN TO LEFT-LABEL-OUT         (overwrite)
    MOVE SPACES TO BLANK-OUT
    MOVE NAME-IN TO RIGHT-LABEL-OUT
    MOVE ADDRESS-IN TO RIGHT-LABEL-OUT               (overwrite)
    MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT        (overwrite)
    MOVE SPACES TO BLANK-A-OUT
    WRITE LABEL-RECORD-OUT                           (only wrote one line)

C'est le paragraphe qui traite enregistrement. Ce que vous faites ici, c'est mettre trois choses à gauche et à droite. sections de sortie (de sorte que les deux premières sont écrasées).

ce dont vous avez besoin est une variable à bascule pour sélectionner si vous traitez une valeur gauche ou une valeur droite, et la capacité de stocker les données à gauche afin que vous puissiez les afficher quand vous traitez les bonnes données, quelque chose comme:

WORKING-STORAGE SECTION.
    01 ARE-THERE-MORE-RECORDS     PIC X(3) VALUE 'YES'.
    01 DOING-LEFT                 PIC X(3) VALUE 'YES'.
    01 LEFT-NAME-IN               PIC X(20).
    01 LEFT-ADDRESS-IN            PIC X(20).
    01 LEFT-CITY-STATE-ZIP-IN     PIC X(20).

puis modifiez votre code de traitement d'enregistrement ainsi (cochez la case IF syntaxe, ça fait longtemps que je n'ai pas coupé de COBOL le code):

200-PROCESS-ONE-RECORD.
    IF DOING-LEFT = 'YES' THEN
        PERFORM 201-PROCESS-LEFT-RECORD
    ELSE
        PERFORM 202-PROCESS-RIGHT-RECORD.

201-PROCESS-LEFT-RECORD.
    MOVE NAME-IN TO LEFT-NAME-IN.                      (just store it)
    MOVE ADDRESS-IN TO LEFT-ADDRESS-IN.
    MOVE CITY-STATE-ZIP-IN TO LEFT-CITY-STATE-ZIP.
    MOVE 'NO' TO DOING-LEFT.                           (and toggle to right)

202-PROCESS-RIGHT-RECORD.
    MOVE LEFT-NAME-IN TO LEFT-LABEL-OUT.               (first line, both sides)
    MOVE SPACES TO BLANK-OUT.
    MOVE NAME-IN TO RIGHT-LABEL-OUT.
    MOVE SPACES TO BLANK-A-OUT.
    WRITE LABEL-RECORD-OUT.

    MOVE LEFT-ADDRESS-IN TO LEFT-LABEL-OUT.            (second line, both sides)
    MOVE SPACES TO BLANK-OUT.
    MOVE ADDRESS-IN TO RIGHT-LABEL-OUT.
    MOVE SPACES TO BLANK-A-OUT.
    WRITE LABEL-RECORD-OUT.

    MOVE LEFT-CITY-STATE-ZIP-IN TO LEFT-LABEL-OUT.     (third line, both sides)
    MOVE SPACES TO BLANK-OUT.
    MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT.
    MOVE SPACES TO BLANK-A-OUT.
    WRITE LABEL-RECORD-OUT.

    MOVE 'YES' TO DOING-LEFT.                          (toggle back to left)

ensuite, à la fin, après que le fichier a été entièrement lu, vous devez détecter si vous avez rempli les données de gauche (i.e., il y avait un nombre impair de lignes d'entrée). Ce sera le cas si DOING-LEFT est réglé sur 'NO'.

je vous laisse faire mais cela implique de déplacer les données de gauche et de peupler les données de droite avec des espaces, d'une manière très type 202-PROCESS-RIGHT-RECORD ci-dessus (coup de coude, coup de pouce,clin d'oeil, clin d'oeil).


Et, maintenant que j'ai eu un bonne regardez la sortie désirée, il semble que vous ayez besoin de deux copies de chaque adresse sur la gauche et la droite. Êtes-vous sûr que c'est la façon dont vous voulez le faire puisque c'est une exigence assez inhabituelle pour un programme d'étiquette postale?

dans tous les cas, je vais laisser tout ce code ci-dessus car c'est une bonne façon de faire le Un-chaque méthode d'étiquettes de mailing mais le code que vous semblez avoir besoin est beaucoup plus simple, une très légère variation de 202-PROCESS-RIGHT-RECORD paragraphe.

Oubliez tout le stockage de travail supplémentaire que j'ai mentionné, et juste changer 200-PROCESS-ONE-RECORD à:

200-PROCESS-ONE-RECORD.
    MOVE NAME-IN TO LEFT-LABEL-OUT.
    MOVE SPACES TO BLANK-OUT.
    MOVE NAME-IN TO RIGHT-LABEL-OUT.
    MOVE SPACES TO BLANK-A-OUT.
    WRITE LABEL-RECORD-OUT.

    MOVE ADDRESS-IN TO LEFT-LABEL-OUT.
    MOVE SPACES TO BLANK-OUT.
    MOVE ADDRESS-IN TO RIGHT-LABEL-OUT.
    MOVE SPACES TO BLANK-A-OUT.
    WRITE LABEL-RECORD-OUT.

    MOVE CITY-STATE-ZIP-IN TO LEFT-LABEL-OUT.
    MOVE SPACES TO BLANK-OUT.
    MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT.
    MOVE SPACES TO BLANK-A-OUT.
    WRITE LABEL-RECORD-OUT.
9
répondu paxdiablo 2010-10-21 23:28:02

votre question est déjà bien répondue sur les overwrites, mais je voudrais ajouter deux choses qui amélioreront grandement votre code Cobol en lisibilité et maintenabilité.

vous utilisez un meme Cobol '74 ici avec la variable" ARE-THERE-MORE-RECORDS "et en déplaçant les lettres" YES " et " NO " vers celle-ci. C'est très fragile et susceptible de se briser. Une approche beaucoup plus agréable, moins fragile, plus lisible est d'utiliser les conditionnels que Cobol fournit, également connu sous le nom 88:

  05 Filler          Pic x(1) Value 'Y'.
    88 More-Records           Value 'Y'.
    88 No-More-Records        Value 'N'.

Vous pouvez le tester avec:

 Perform until No-More-Records

Et les déclencher à:

 Set No-More-Records to true

Cela fait plusieurs choses pour vous.

  • personne ne maintiendra jamais accidentellement l'une de vos littérales à " non "au lieu de" non " ou d'autre munge votre code source. Cela peut être un vrai problème sur les systèmes plus anciens qui font des hypothèses sur le cas supérieur / inférieur pour leurs utilisateurs et leurs attachées terminal.

  • personne ne peut déplacer 'BOB' à votre drapeau parce que vous ne lui avez pas donné un nom, vous l'avez fait remplir. Ils vont sortir de leur façon d'attribuer à une variable au lieu d'utiliser la condition de noms. Et s'ils sont assez capables pour aller aussi loin, ils sont assez capables pour savoir pourquoi ils ne devraient pas le faire.

  • il donne le contrôle de votre boucle et le contrôle des fichiers vérifie les noms significatifs. Accordé, sont-là-plus-dossiers "OUI"/ " NON "est assez significatif, mais dans le vrai code de production vous rencontrerez de nombreuses conditions différentes, souvent avec des noms inhabituels et une logique déformée derrière eux, parfois" oui " / " non " n'est pas aussi clair qu'il pourrait l'être. Donner un nom de condition agréable, long de 30 caractères est beaucoup plus facile pour les programmeurs qui vous suivront pour faire l'entretien.

L'autre chose que vous faire est d'utiliser le système de numérotation des paragraphes. C'était une mauvaise idée quand le papier graphique coule les cartes étaient toute la documentation que vous aviez et le contrôle source n'était pas encore un clin d'œil.

100-MAIN.
200-PROCESS-ONE-RECORD.

il ne vous achète pas vraiment rien, et il est livré avec plusieurs inconvénients.

avec le contrôle des sources moderne, les changements à tous les autres numéros de paragraphe qui ne sont pas liés au changement spécifique que vous faites se démarqueront comme un pouce endolori. (En supposant que quelqu'un renomme ses paragraphes quand leur logique change, ce qu'ils ne font jamais)

Il encourage vraiment merdique paragraphe noms. Considérez ceci, parfaitement valide sous le système de numérotation des paragraphes:

  100-Read-File
  200-Read-File
  300-Read-File
  110-Write-File
  210-Write-File
  310-Write-File

nous avons évidemment trois fichiers différents, ou au moins trois combinaisons de fichiers et types de lecture, mais absolument aucune indication de ce qui est différent par le nom du paragraphe. Il est également sujet à l'erreur de cut&paste où quelqu'un Copie un paragraphe, le renomme, et ne modifie pas complètement le contenu pour frapper le nouveau fichier ou définir les nouveaux drapeaux conditionnels pour le séparez le fichier, créant ainsi des bugs subtils et difficiles à trouver.

Une bien meilleure approche est la suivante:

  Read-Master-File
  Read-Transaction-File
  Write-Master-File
  Write-Transaction-File
  Write-Log-File

C'est plus facile de bien faire et difficile de faire le mal.

rappelez-vous que vous écrivez du code source pour que d'autres humains le lisent, le compilateur prendra n'importe quelle sorte de merde, mais votre maintenance est à 90% du cycle de vie d'un programme et cela signifie que d'autres personnes* passeront dix fois plus de temps à essayer de comprendre ce que vous avez écrit que vous avez passé à l'écrire. Le rendre facile pour ils.

  • Très souvent, ce sera vous, mais vous ne reconnaîtra pas le code que vous avez écrit il y a six mois...
1
répondu Joe Zitzelberger 2012-09-17 05:22:56