Странная ошибка COBOL
Прежде всего, вот полный исходный код: http://pastebin.com/5teGNrPC
*>
IDENTIFICATION DIVISION.
PROGRAM-ID. CAddress.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT TelephoneBookFile
ASSIGN TO "phonebook.db"
ORGANIZATION IS INDEXED
RECORD KEY IS user-record-key
ACCESS MODE IS DYNAMIC.
DATA DIVISION.
FILE SECTION.
FD TelephoneBookFile
LABEL RECORDS ARE STANDARD.
01 User-Record-File.
05 user-record-key PIC X(35).
05 user-record-first-name PIC X(24).
05 user-record-last-name PIC X(50).
05 user-record-address PIC X(50).
05 user-record-city PIC X(16).
05 user-record-zip PIC X(8) .
05 user-record-country PIC X(20).
05 user-record-telephone PIC X(16).
WORKING-STORAGE SECTION.
77 menu-hoofd-invoer PICTURE 9(1) VALUE 9.
88 menu-invoer-correct VALUE 0 THRU 5.
88 menu-invoer-incorrect VALUE 6 THRU 9.
88 menu-invoer-afsluiten VALUE 0.
88 menu-invoer-record-toevoegen VALUE 1.
88 menu-invoer-nieuw-bestand VALUE 5.
77 Error-Msg PICTURE X(30) VALUE " ".
77 Green-Msg PICTURE X(30) VALUE " ".
77 file-status PICTURE X(3) VALUE " ".
88 file-status-eof VALUE "EOF".
01 User-Record.
05 user-first-name PIC X(24).
05 user-last-name PIC X(50).
05 user-address PIC X(50).
05 user-city PIC X(16).
05 user-zip PIC X(8) .
05 user-country PIC X(20).
05 user-telephone PIC X(16).
77 Yes-No-Correct-Field PICTURE X(1) VALUE " ".
88 yes-no-field-yes VALUE "Y" "y".
88 yes-no-field-no VALUE "N" "n".
88 yes-no-field-correct VALUE "C" "c".
77 Record-Count PIC 9(5) VALUE 0.
77 Error-Screen-Msg PIC X(45) VALUE SPACES.
77 Navigate-Field PICTURE X(1) VALUE " ".
88 Navigate-Next VALUE "N" "n".
88 Navigate-Prev VALUE "P" "p".
88 Navigate-Exit VALUE "X" "x".
77 Error-Continue-Flag PIC X(1) VALUE " ".
88 Error-Continue-OK VALUE "C" "c".
SCREEN SECTION.
01 MainMenu.
05 BLANK SCREEN.
05 LINE 1 COLUMN 1 VALUE " CAddress - A COBOL Address Book".
05 LINE 2 COLUMN 1 VALUE " -------------------------------".
05 LINE 4 COLUMN 1 VALUE " Make your choice: ".
05 LINE 5 COLUMN 1 VALUE " ~~~~~~~~~~~~~~~~~ ".
05 LINE 7 COLUMN 1 VALUE " 1) Add record".
05 LINE 8 COLUMN 1 VALUE " 2) Delete record".
05 LINE 9 COLUMN 1 VALUE " 3) Look up record".
05 LINE 10 COLUMN 1 VALUE " 4) Show records".
05 LINE 11 COLUMN 1 VALUE " 5) Create new file".
05 LINE 13 COLUMN 1 VALUE " 0) Exit".
05 LINE 15 COLUMN 1 VALUE " Choice? ".
05 LINE 15 COLUMN 25 PICTURE X(30) FROM Error-Msg FOREGROUND-COLOR 4.
05 LINE 24 COLUMN 1 VALUE " (c) YvanSoftware ".
01 InvoerMenu.
05 BLANK SCREEN.
05 LINE 1 COLUMN 1 VALUE " CAddress - A COBOL Address Book".
05 LINE 2 COLUMN 1 VALUE " -------------------------------".
05 LINE 4 COLUMN 1 VALUE " Input Data".
05 LINE 5 COLUMN 1 VALUE " ~~~~~~~~~~".
05 LINE 7 COLUMN 1 VALUE " First name :" FOREGROUND-COLOR 2.
05 LINE 8 COLUMN 1 VALUE " Last name :" FOREGROUND-COLOR 2.
05 LINE 9 COLUMN 1 VALUE " Address :" FOREGROUND-COLOR 2.
05 LINE 10 COLUMN 1 VALUE " City :" FOREGROUND-COLOR 2.
05 LINE 11 COLUMN 1 VALUE " ZIP :" FOREGROUND-COLOR 2.
05 LINE 12 COLUMN 1 VALUE " Country :" FOREGROUND-COLOR 2.
05 LINE 13 COLUMN 1 VALUE " Telephone :" FOREGROUND-COLOR 2.
05 LINE 15 COLUMN 1 VALUE " Save? y(es)/n(o)/c(orrect) " FOREGROUND-COLOR 4.
05 LINE 24 COLUMN 1 VALUE " (c) YvanSoftware ".
01 UitvoerScherm.
05 BLANK SCREEN.
05 LINE 1 COLUMN 1 VALUE " CAddress - A COBOL Address Book".
05 LINE 2 COLUMN 1 VALUE " -------------------------------".
05 LINE 4 COLUMN 1 VALUE " Find Data".
05 LINE 5 COLUMN 1 VALUE " ~~~~~~~~~~".
05 LINE 7 COLUMN 1 VALUE " First name :" FOREGROUND-COLOR 2.
05 LINE 8 COLUMN 1 VALUE " Last name :" FOREGROUND-COLOR 2.
05 LINE 9 COLUMN 1 VALUE " Address :" FOREGROUND-COLOR 2.
05 LINE 10 COLUMN 1 VALUE " City :" FOREGROUND-COLOR 2.
05 LINE 11 COLUMN 1 VALUE " ZIP :" FOREGROUND-COLOR 2.
05 LINE 12 COLUMN 1 VALUE " Country :" FOREGROUND-COLOR 2.
05 LINE 13 COLUMN 1 VALUE " Telephone :" FOREGROUND-COLOR 2.
* Col 45 Input
05 LINE 15 COLUMN 1 VALUE " Navigate? n(ext)/p(revious)/x(exit) " FOREGROUND-COLOR 4.
05 LINE 24 COLUMN 1 VALUE " (c) YvanSoftware ".
01 FoutScherm.
05 BLANK SCREEN.
05 LINE 4 COLUMN 15 VALUE "====================(ERROR)======================" BACKGROUND-COLOR 4 FOREGROUND-COLOR 7.
05 LINE 5 COLUMN 15 VALUE " " BACKGROUND-COLOR 4 FOREGROUND-COLOR 7.
05 LINE 6 COLUMN 15 VALUE " " BACKGROUND-COLOR 4 FOREGROUND-COLOR 7.
05 LINE 7 COLUMN 15 VALUE " " BACKGROUND-COLOR 4 FOREGROUND-COLOR 7.
05 LINE 8 COLUMN 15 VALUE " " BACKGROUND-COLOR 4 FOREGROUND-COLOR 7.
05 LINE 10 COLUMN 15 VALUE " INPUT C TO CONTINUE " BACKGROUND-COLOR 4 FOREGROUND-COLOR 7.
05 LINE 6 COLUMN 18 PICTURE X(45) FROM Error-screen-msg BACKGROUND-COLOR 4 FOREGROUND-COLOR 7 BLINK.
PROCEDURE DIVISION.
main.
PERFORM Show-MainMenu UNTIL menu-invoer-afsluiten.
STOP RUN.
.
Show-MainMenu.
DISPLAY MainMenu
ACCEPT menu-hoofd-invoer LINE 15 COLUMN 22.
IF menu-invoer-incorrect
THEN
MOVE " Incorrect input" TO Error-Msg
MOVE " " TO Green-Msg
END-IF.
IF menu-invoer-record-toevoegen
THEN
PERFORM Show-InvoerMenu
END-IF
IF menu-invoer-nieuw-bestand
THEN
PERFORM Show-NewFile
END-IF.
.
Show-InvoerMenu.
DISPLAY InvoerMenu.
ACCEPT user-first-name LINE 7 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-last-name LINE 8 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-address LINE 9 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-city LINE 10 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-zip LINE 11 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-country LINE 12 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-telephone LINE 13 COLUMN 18
WITH FOREGROUND-COLOR 4.
PERFORM AskForSave.
.
Show-NewFile.
DISPLAY InvoerMenu.
ACCEPT user-first-name LINE 7 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-last-name LINE 8 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-address LINE 9 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-city LINE 10 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-zip LINE 11 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-country LINE 12 COLUMN 18
WITH FOREGROUND-COLOR 4.
ACCEPT user-telephone LINE 13 COLUMN 18
WITH FOREGROUND-COLOR 4.
PERFORM AskForSaveNew.
AskForSave.
ACCEPT Yes-No-Correct-Field LINE 15 COLUMN 35
WITH FOREGROUND-COLOR 2.
IF Yes-No-Field-Correct
THEN
PERFORM Show-InvoerMenu
END-IF.
IF Yes-No-Field-No
THEN
PERFORM Show-MainMenu
END-IF.
IF Yes-No-Field-Yes
THEN
PERFORM Save-Record
END-IF.
IF NOT Yes-No-Field-No AND NOT Yes-No-Field-Yes AND NOT Yes-No-Field-Correct
THEN
PERFORM AskForSave
END-IF.
.
Save-Record.
OPEN I-O TelephoneBookFile.
PERFORM AddRecordKey.
MOVE user-first-name TO user-record-first-name.
MOVE user-last-name TO user-record-last-name .
MOVE user-address TO user-record-address .
MOVE user-city TO user-record-city .
MOVE user-zip TO user-record-zip .
MOVE user-country TO user-record-country .
MOVE user-telephone TO user-record-telephone .
WRITE User-Record-File INVALID KEY PERFORM ExistsAlready.
CLOSE TelephoneBookFile
.
AskForSaveNew.
ACCEPT Yes-No-Correct-Field LINE 15 COLUMN 35
WITH FOREGROUND-COLOR 2.
IF Yes-No-Field-Correct
THEN
PERFORM Show-NewFile
END-IF.
IF Yes-No-Field-No
THEN
PERFORM Show-MainMenu
END-IF.
IF Yes-No-Field-Yes
THEN
PERFORM Save-Record-NewFile
END-IF.
IF NOT Yes-No-Field-No AND NOT Yes-No-Field-Yes AND NOT Yes-No-Field-Correct
THEN
PERFORM AskForSave
END-IF.
.
Save-Record-NewFile.
OPEN OUTPUT TelephoneBookFile.
PERFORM AddRecordKey.
MOVE user-first-name TO user-record-first-name.
MOVE user-last-name TO user-record-last-name .
MOVE user-address TO user-record-address .
MOVE user-city TO user-record-city .
MOVE user-zip TO user-record-zip .
MOVE user-country TO user-record-country .
MOVE user-telephone TO user-record-telephone .
WRITE User-Record-File.
CLOSE TelephoneBookFile.
.
AddRecordKey.
STRING user-first-name(1:5) user-last-name(1:5)
user-address(1:5) user-city(1:5)
user-zip(1:5) user-country(1:5)
user-telephone(1:5)
DELIMITED BY SIZE
INTO user-record-key
.
ExistsAlready.
MOVE "Record already exists" TO Error-Screen-Msg
PERFORM ErrorScreen
.
ErrorScreen.
DISPLAY FoutScherm
ACCEPT Error-Continue-Flag LINE 24 COLUMN 80
IF NOT Error-Continue-OK
THEN
Perform ErrorScreen
END-IF.
.
END PROGRAM CAddress.
Я получаю странную ошибку COBOL, и я не могу найти, что это значит. Там написано Open Error (см. Следующий скриншот).
Это не происходит, если я сначала использую "новый файл", и после этого добавляю запись.
Вот бинарный файл приложения и некоторые файлы журнала, которые он создал.
Большое спасибо,
Yvan
PS: это диалект Fujitsu NetCobol.
3 ответа
Я хотел бы получить немного больше информации о проблеме с файловым вводом / выводом, которая у вас возникла. Если я правильно понимаю, вы можете сделать следующее без проблем:
- Создать новый файл
- Добавить запись
- Выход
Затем, если вы запустите программу снова и сразу
- Добавить запись
программа бомбит с "странной ошибкой".
Возможно ли вам прочитать и отобразить запись, которую вы написали в первом запуске? Мне интересно, если предыдущая запись была успешной, что, в свою очередь, ставит под сомнение целостность файла.
Я хотел бы предложить изучить OPTIONAL
ключевое слово для SELECT
и добавив FILE STATUS
пункт тоже. Состояние файла следует проверять после каждой операции ввода-вывода (ОТКРЫТО, ЗАКРЫТЬ, ЗАПИСАТЬ, ПРОЧИТАТЬ и т. Д.). Значение, содержащееся в переменной, связанной с FILE STATUS
займет у вас долгий путь к решению проблемы. Следующая таблица описывает FILE STATUS
ценности.
Вы также можете просмотреть этот учебник по обработке проиндексированных файлов в COBOL.
Возможно, я не понял, в чем проблема с вашим файловым вводом / выводом, но я вижу что-то еще, что позже может вызвать проблемы!
Вы использовали следующую конструкцию:
PERFORM Some-Paragraph
...
Some-Paragraph.
...
IF Some-Condition
PERFORM Some-Paragraph
END-IF
.
Последний PERFORM Some-Paragraph
находится в рамках самого абзаца. Компиляторы COBOL могут не пометить это как ошибку, но поведение не определено. COBOL PERFORM не соответствует семантике CALL/RETURN, с которой вы, возможно, знакомы по другим языкам. То, что вы здесь закодировали, обычно называют "логической бомбой". Подробное описание того, что я имею в виду, можно найти здесь.
Первая ошибка, вероятно, ошибка 35 состояния файла, открывающая файл, который не существует. Вы должны реструктурировать свой код. В программе ввода данных необходимо, чтобы операторы OPEN и CLOSE выполнялись только один раз. В этой программе оператор OPEN должен быть расположен как можно ближе к началу исходного кода (для однократного выполнения в начале, а также для удобства чтения), а CLOSE должен быть непосредственно перед STOP RUN.
Возможно, программа пытается получить доступ к файлу до его создания. Опция 'new file', вероятно, создает файл данных с оператором OPEN OUTPUT, и добавление записи будет успешным.