2010-10-21 11 views
14

Przykro mi, że przeszkadzam wszystkim, ale utknąłem w mojej pracy domowej dla COBOL. Zrobiłem dwie próby, z których żadna nie działa zgodnie z oczekiwaniami.Potrzebujesz pomocy z moimi zadaniami domowymi COBOL

Dwie próby i ich wyniki są pokazane poniżej, a następnie ostateczne wyniki, które muszą być. Dziękuję wszystkim za pomoc.

Pierwsza próba:

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. 

ta produkuje:

*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 

Moja druga próba:

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 

produkowane:

*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 

Co muszę skończyć ze jest coś takiego jak:

*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 

Co się dzieje z mojego kodu?

Odpowiedz

3

Myślę, że druga próba była prawie poprawne. Jak Paxdiablo wskazywał w swojej odpowiedzi, problem polega na tym, że nadpisujesz dane.

Jeśli dobrze rozumiem Twój problem, czytasz w jednym zapisie zawierający pełny adres (imię i nazwisko, adres, miasto-stan-Zip) i musisz wydrukować dwie kopie obok siebie.

Należy zauważyć, że dla każdej przeczytanej linii należy wydrukować 3. Należy również zauważyć, że użytkownik ma tylko jeden bufor rekordów wyjściowych. Oznacza to, że można przetworzyć tylko jedną linię wyjściową o godzinie . Rozwiązaniem jest przeniesienie każdego komponentu adresu na lewą i prawą stronę linii wyjściowej, wyprowadzenie linii, a następnie przejście do następnego komponentu adresu. Od są 3 komponenty adresu, kończysz drukowanie 3 wierszy dla każdego przeczytanego.

Spróbuj modyfikację pkt 200-Process-ONE-Record następująco

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 

ten trwa jedną linię wejściową, produkuje 3 linie wyjściowe. Możesz chcieć wypisać czwartą pustą linię, aby oddzielić adresy (jak pokazano na przykładowym wyjściu - będę mógł pozwolić ci wymyślić jak to zrobić).

Myślę, że rozwiązanie Paxdiablo rozwiązało nieco inny problem, , w którym drukujesz jedną kopię każdego adresu, ale drukujesz 2 adresy.

BTW ... Pomimo wielu dyskredytujących komentarzy "przejedź obok", twoje pytanie się pojawiło, COBOL jest nadal aktywnie wykorzystywany w niektórych segmentach tej branży.

+0

@After wypróbowanie wersji paxdiablo i spanie na nim obudziłem się z pomysłem tylko tak jak ten, pamiętając, że pisał tam iz powrotem za każdym razem, gdy wprowadzano nowe dane.Zrobiłeś to z wszystkich względów, z wyjątkiem tego, że musiałem znaleźć miejsce między etykietami, ale w tym celu zrobiłem kolejny akapit kodu i wysłałem spacje do każdego pola. Dziękuję za pomoc. – Kimmy1235

+0

Aarrgghh, spędziłem 10 minut, zastanawiając się, co oznacza twój komentarz na temat mojej odpowiedzi i naprawiając kod tylko po to, by zobaczyć, że już odpowiedziałeś z tym samym kodem (Scène à faire, chyba COBOL na drugim końcu spektrum od sposobu myślenia Perla "jest miliard sposobów na zrobienie tego"). W każdym razie +1 dla lepszej odpowiedzi. – paxdiablo

+0

Możesz przesunąć spacje na poziomie 01 do rekordu wyjściowego, ale jeśli dobrze pamiętam, jest to potrzebne tylko raz, gdy program się rozpocznie i nie jest potrzebny w pętli. –

9

Zwykle nie udzielam tak dużo pomocy w odrabianiu prac domowych, ale skoro już włożyłeś w to sporo wysiłku i prawdopodobnie nie znajdziesz tutaj wielu z nas dinozaurów, pomogę ci .

Twój problem jest tutaj (ignorować rzeczy w nawiasach po prawej stronie, są one po prostu komentuje ci pomóc):

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) 

To jest akapit, który przetwarza jeden rekord. To, co tutaj robisz, polega na umieszczeniu trzech rzeczy w lewej i prawej sekcji wyjściowej (tak, że pierwsze dwa są nadpisywane).

To, czego potrzebujesz, to przełączanie zmiennej, aby wybrać, czy przetwarzasz lewą wartość lub prawą wartość, oraz możliwość zapisania lewych danych, aby móc je wyprowadzać zarówno podczas przetwarzania właściwych danych, jak i danych jak:

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). 

Następnie zmodyfikować kod przetwarzanie rekord ten sposób (sprawdź składnię IF, minęło trochę czasu odkąd wyciąć dowolny kod COBOL):

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) 

Następnie, na końcu, po pliku ma został w pełni odczytany, musisz wykryć, czy wypełniłeś lewe dane (tj. wystąpiła nieparzysta liczba linii wejściowych). Tak będzie w przypadku, gdy DOING-LEFT jest ustawione na 'NO'.

Zostawię to dla ciebie, ale to wymaga przemieszczania lewej danych i wypełniania odpowiednich danych z przestrzeni, w sposób bardzo podobny do 202-PROCESS-RIGHT-RECORD powyżej (sugerować, szturchać, wink, wink). teraz, że miałem dobrą obejrzenia pożądanym wyjściem wydaje


I rzeczywiście potrzebne są dwie kopie każdego adresu na zarówno lewo i prawo.Jesteś pewien, że tak właśnie chcesz to zrobić, ponieważ jest to dość nietypowy wymóg dla programu do etykietowania wiadomości?

W każdym razie pozostawię cały powyższy kod, ponieważ jest to dobry sposób na wykonanie każdej z metod wysyłania etykiet, ale kod, który wydaje się wam potrzebny, jest znacznie prostszy, bardzo nieznaczną odmianę 202-PROCESS-RIGHT-RECORD ustęp.

Zapomnij wszystkie dodatkowe przechowywanie pracuje już wspomniałem, i wystarczy zmienić 200-PROCESS-ONE-RECORD do:

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. 
1

Twoje pytanie jest już dobrze odpowiedzi na temat nadpisuje, ale chciałbym dodać dwie rzeczy, które znacznie poprawi twój kod Cobol w czytelności i łatwości konserwacji.

Używasz tu mema Cobola '74 ze zmienną ARE-THERE-MORE-RECORDS i przenoszącymi do niej literami "TAK" i "NIE". Jest to bardzo kruche i podatne na pękanie. O wiele ładniejszy, mniej łamliwe, bardziej czytelny podejście jest użycie warunkowe że Cobol przewiduje znany również jako 88 to:

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

można przetestować go z:

Perform until No-More-Records 

i wywoływać go z:

Set No-More-Records to true 

To robi kilka rzeczy dla ciebie.

  • Nikt nigdy przypadkowo utrzymać jeden z literałów na „nie” zamiast „NIE” lub inaczej munge się kod źródłowy. Może to stanowić poważny problem w starszych systemach, które przyjmują założenia dotyczące dużych/małych liter dla użytkowników i podłączonych do nich terminali.

  • Nikt nie może przenieść "BOB" na swoją flagę, ponieważ nie podałeś jej nazwy, zrobiłeś ją wypełniaczem. Muszą wyjść z drogi, aby przypisać do tej zmiennej, zamiast używać nazw warunków. A jeśli są wystarczająco zdolni, aby odejść tak daleko, są na tyle zdolni, aby wiedzieć, dlaczego NIE POWINNI.

  • Daje kontroli pętli i kontroli plików znaczące nazwy. To prawda, że ​​TREŚĆ WIĘCEJ-REKORDÓW "TAK"/"NIE" jest całkiem sensowne, ale w prawdziwym kodzie produkcji napotkasz wiele różnych warunków, często z nietypowymi nazwami i pokrętną logiką, czasami "TAK"/"NIE" nie jest tak jasne, jak mogłoby być. Nadanie fajnej, 30-znakowej nazwie stanu jest znacznie prostsze dla programistów, którzy będą podążać za tobą w celu wykonania konserwacji.

Inną czynnością jest użycie systemu numerowania akapitów. To był kiepski pomysł, gdy wykresy przepływu papieru graficznego były całą dokumentacją, którą posiadaliście, a kontrola źródła nie była jeszcze błyskiem w czyimś oku.

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

To tak naprawdę nic nie kupuje, i ma kilka wad.

Dzięki nowoczesnemu sterowaniu źródłami zmiany wszystkich innych numerów akapitów, które nie są związane z konkretną zmianą, będą wyróżniać się jak bolesny kciuk. (Zakładając, że ktokolwiek kiedykolwiek zmienia numerację swoich akapitów, gdy zmienia się logika, której nigdy nie robią)

Zachęca naprawdę przygnębiające nazwy akapitów. Rozważ to, całkowicie poprawny pod systemem numeracji ustęp:

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

Mamy oczywiście trzy różne pliki, albo przynajmniej trzy kombinacje typów plików i czytać, ale absolutnie nie wskazuje na to, co różni się od nazwy ust. Jest również podatny na przecięty błąd wklejenia &, w którym ktoś kopiuje akapit, ponownie go numeruje i nie zmienia w pełni treści, aby trafić nowy plik lub ustawił nowe flagi warunkowe dla oddzielnego pliku, tworząc w ten sposób subtelne i trudne do znalezienia błędy.

O wiele lepszym rozwiązaniem jest:

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

To jest łatwiej zrobić prawo i trudniej zrobić źle.

Pamiętaj, że piszesz kod źródłowy do czytania dla innych ludzi, kompilator podejmie jakieś bzdury, ale twoje utrzymanie to 90% cyklu życia programów, a to oznacza, że ​​inni ludzie * spędzą dziesięć razy więcej czasu, próbując zrozumieć co napisałeś podczas pisania. Ułatw im to.

  • Bardzo często, to zostaniesz, ale nie rozpozna kod zapisany sześć miesięcy temu ...