Нужна помощь с домашним заданием на COBOL - PullRequest
14 голосов
/ 21 октября 2010

Извините, что беспокою вас всех, но я застрял на домашней работе для COBOL.Я сделал две попытки, ни одна из которых не работает, как ожидалось.

Две попытки и их результаты показаны ниже, за которыми следуют окончательные результаты, которые должны быть.Я благодарю всех вас за вашу помощь.

Первая попытка:

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.

Это дает:

*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

Моя вторая попытка:

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

made:

*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

Что мне нужно , чтобы закончить, это что-то вроде:

*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

Что не так с моим кодом?

Ответы [ 3 ]

9 голосов
/ 21 октября 2010

Обычно я бы не стал так сильно помогать с домашним заданием, но, поскольку вы уже приложили немало усилий и вряд ли найдете здесь многих из нас, динозавров, я помогу вам.

Ваша проблема здесь (не обращайте внимания на то, что указано в скобках справа, это просто комментарии, которые помогут вам):

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)

Этот параграф обрабатывает один запись.То, что вы делаете здесь, это помещает три вещи в левый и правый разделы вывода (так что первые два перезаписываются).

Вам нужна переменная-переключатель, чтобы выбрать, обрабатываете ли вы левую часть.значение или правильное значение, а также возможность сохранять левые данные, чтобы вы могли выводить их оба при обработке правильных данных, что-то вроде:

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

Затем измените обработку записейкод (проверьте синтаксис IF, прошло много времени с тех пор, как я вырезал любой код 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)

Затем, в конце, после того, как файл полностью прочитан, вам нужно определить,Вы заполнили левые данные (т.е. было нечетное количество входных строк).Это будет иметь место, если DOING-LEFT установлен на 'NO'.

Я оставлю это вам, но это включает перемещение левых данных и заполнение правых данных пробелами, в порядке очень аналогично 202-PROCESS-RIGHT-RECORD выше (подтолкнуть, подтолкнуть, подмигнуть, подмигнуть).


И теперь, когда у меня был хороший взгляд на желаемый результатПохоже, вам на самом деле нужны две копии каждого адреса на , оба слева и справа.Вы уверены, что хотите именно так, потому что это довольно необычное требование для программы почтовой метки?

В любом случае я оставлю весь этот код выше, так как это хороший способ сделатьиндивидуальный метод рассылки меток, но код, который вам нужен, гораздо проще, очень незначительный вариант абзаца 202-PROCESS-RIGHT-RECORD.

Забудьте все дополнительное рабочее хранилище, о котором я говорил, и просто измените 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.
4 голосов
/ 21 октября 2010

Я думаю, что ваша вторая попытка была почти правильной.Как указал Паксдиабло в своем ответе, у вас проблема с перезаписью данных.

Если я правильно понимаю вашу проблему, вы читаете одну запись, содержащую полный адрес (имя, адрес, город-штат-почтовый индекс)и вы должны распечатать две его копии бок о бок.

Обратите внимание, что для каждой прочитанной строки необходимо печатать 3. Также обратите внимание, что у вас есть только один буфер выходных записей.Это означает, что вы можете обрабатывать только одну выходную строку за раз.Решение состоит в том, чтобы переместить каждый компонент адреса в левую и правую часть выходной линии, вывести строку и затем перейти к следующему компоненту адреса.Поскольку имеется 3 адресных компонента, вы в конечном итоге напечатаете 3 строки для каждого прочитанного.

Попробуйте изменить параграф 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 

Это займет одну строку ввода, производит 3 выходные строки.Возможно, вы захотите вывести четвертую пустую строку для разделения адресов (как показано в вашем примере вывода - я дам вам понять, как это сделать).

Я думаю, что решение Paxdiablo решило немного другую проблему, когда выбудет печатать по одной копии каждого адреса, но печатать адреса по ширине 2.

Кстати ... Несмотря на количество уничижительных комментариев «по запросу», которые получил ваш вопрос, COBOL по-прежнему активно используется в некоторых сегментах этой отрасли.

2 голосов
/ 17 сентября 2012

На ваш вопрос уже есть хорошие ответы по поводу перезаписей, но я бы добавил две вещи, которые значительно улучшат ваш код Cobol в удобочитаемости и удобстве обслуживания.

Вы используете мем Cobol '74 здесь с ARE-Переменная THERE-MORE-RECORDS и перемещение литералов 'YES' и 'NO' в нее.Это очень хрупкий и склонный к поломке.Гораздо более приятный, менее хрупкий и более читаемый подход заключается в использовании условий, которые предоставляет Cobol, также известных как 88:

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

. Вы можете проверить это с помощью:

 Perform until No-More-Records

И триггераэто с:

 Set No-More-Records to true

Это делает несколько вещей для вас.

  • Никто никогда не будет случайно поддерживать один из ваших литералов в «нет» вместо «НЕТ» илииначе испортите ваш исходный код.Это может быть реальной проблемой на старых системах, которые делают предположения о верхнем / нижнем регистре для своих пользователей и подключенных терминалов.

  • Никто не может переместить 'BOB' на ваш флаг, потому что вы не сделали 'дать ему имя, вы сделали это наполнителем.Они должны сделать все возможное, чтобы присвоить эту переменную вместо использования имен условий.И если они достаточно способны, чтобы пойти так далеко, они способны понять, почему они НЕ ДОЛЖНЫ это делать.

  • Это дает вам контроль за циклами и контроль файловзначимые имена.Конечно, ARE-THERE-MORE-RECORDS 'YES' / 'NO' является довольно значимым, но в реальном производственном коде вы столкнетесь с множеством различных условий, часто с необычными именами и запутанной логикой, иногда «YES» / «NO»не так ясно, как могло бы быть.Программистам, которые будут следовать за вами для сопровождения, гораздо проще дать хорошее имя из 30 символов.Это была плохая идея, когда на диаграммах в виде миллиметровой бумаги была вся документация, которая у вас была, а контроль источников еще ни для кого не был мерцанием.

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

    Это на самом деле ничего вам не покупает, иэто идет с несколькими недостатками.

    При современном управлении исходным кодом изменения всех других номеров абзацев, которые не имеют отношения к конкретному изменению, которое вы делаете, будут выделяться, как больной большой палец.(Предполагая, что кто-нибудь когда-либо изменяет нумерацию своих абзацев, когда их логика меняется, чего они никогда не делают)

    Это поощряет действительно дурацкие названия абзацев.Считайте, что это совершенно справедливо в соответствии с системой нумерации абзацев:

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

    У нас, очевидно, есть три разных файла, или, по крайней мере, три комбинации файлов и типов чтения, но абсолютно нет указаний на то, что отличается именем абзаца.,Он также подвержен ошибке вырезания и вставки, когда кто-то копирует абзац, нумерует его и не полностью изменяет содержимое, чтобы попасть в новый файл или устанавливать новые условные флаги для отдельного файла, создавая тем самым незаметные и трудно обнаруживаемые ошибки.

    Гораздо лучший подход:

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

    Это легче делать правильно и труднее делать неправильно.

    Помните, что вы пишете исходный код для чтения другими людьми, компилятор возьмет на себя всякое дерьмо, но ваше обслуживание составляет 90% жизненного цикла программы, а это значит, что другие люди * потратят в десять раз больше времени на попыткичтобы понять, что вы написали, как вы потратили на это.Облегчи им.

    • Очень часто это будешь ты, но ты не узнаешь код, который написал шесть месяцев назад ...
...