2013-02-04 5 views
2

우리는 108 번 발생하는 이름의 배열을 형성해야합니다. 우리는 왼쪽 열에 1-54라는 이름을두고 오른쪽 열에 55-108을 명명했습니다. 한 페이지에 108 개의 이름이 있으면 우리는 배열을 초기화하고 다시 시작합니다. 내 코드의 출력 결과는 1-54라는 이름이 인쇄되어 있고 같은 페이지에 있고 이름 1-54 이외에 오른쪽 열은 55-108이지만 이름은 1-54입니다. 어떤 생각이라도 대단히 감사하겠습니다. 내가 정보를 수용하기 위해 모든 적절한 WORKING-STORAGE 항목을 코딩 한두 열로 인쇄

 PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO ' 
      READ NAMELIST-FILE-IN 
       AT END 
        MOVE 'NO ' TO ARE-THERE-MORE-RECORDS 
       NOT AT END 
        PERFORM 200-PROCESS-ONE-RECORD 
      END-READ 
     END-PERFORM 
     CLOSE NAMELIST-FILE-IN 
     CLOSE NAMELIST-FILE-OUT 
     STOP RUN. 

    200-PROCESS-ONE-RECORD. 
     ADD 1 TO NAME-SUB 
     MOVE NAME-IN TO NAME-1 (NAME-SUB) 
     PERFORM 220-MOVE-RECORDS. 


    220-MOVE-RECORDS. 
     IF NAME-SUB <= 54 
      MOVE NAME-1 (NAME-SUB) TO LEFT-LABEL 
      MOVE SPACES TO RIGHT-LABEL 
     END-IF 
     IF NAME-SUB >= 55 
      MOVE NAME-1 (NAME-SUB) TO RIGHT-LABEL 
      MOVE SPACES TO LEFT-LABEL 
     END-IF 
     MOVE DETAIL-LINE TO NAMELIST-RECORD-OUT 
     WRITE NAMELIST-RECORD-OUT 
      AFTER ADVANCING 1 LINE 
     IF NAME-SUB >= 108 
      MOVE SPACES TO DETAIL-LINE 
      MOVE ZERO TO NAME-SUB 
      PERFORM 300-WRITE-HEADING 
     END-IF. 

:

여기 내 코드의 일부이다. 세부적인 선을 쓰는 방식에 문제가 있는지 또는 데이터를 처리하는 방식인지 알고 계십니까?

+0

COBOL. 와우 :) 어떤 플랫폼에서 이것을 개발하고 있습니까? PC? 실제 응용 프로그램을 배포 할 대상 플랫폼은 무엇입니까? 학교 용인가요? 작업? 추신 : 예기치 않은 실제 결과물을 게시 할 수있는 기회가 있습니까? – paulsm4

+0

나는 cobol 사람이 아니지만 어딘가에 IF NAME-SUB> = 55 GO TO TOP []가있을 것으로 기대합니다. 또한 '왼쪽으로 레이블을 옮기기'는 이미 존재하는 것을 덮어 쓰지 않을 것입니까? – BevynQ

+0

예 PC를 사용 중이며 학교용입니다. 나는 정말로 그것이 종이 (단지 종이 위에)와 같게 보이기로되어있는 것의 예를 가지고 있지 않다. 그러나 나는 나의 것이 어떻게되고 있는지에 관해 예를 가지고있다. –

답변

3

논리가 잘못되었습니다. 너는 216 개의 이름을 가지고 있다고 말하면서 108 개의 이름을 읽고 그것들을 NAME-1 배열에 저장해야 할 것이다.

NAME-1 [n]을 LEFT-LABEL에 놓고 NAME-1 [n + 54]을 RIGHT-LABEL에 놓고 54 줄을 반복 할 수 있습니다. 그런 다음 세부 줄을 이동하고 출력에 쓸 수 있습니다. n = 1 라인 반복 < = 54

이제 다음 108 줄을 읽고 반복하십시오. 따라서 두 개의 루프; 108 이름 읽기, 54 행 인쇄. 분명히

는 108 명 정확히 배수, 난 당신이 (N 제대로 변수를 설정해야합니다 실현

if n <= name-sub 
    move NAME-1[n] to LEFT-LABEL 
else 
    move spaces to LEFT-LABEL 
endif 

if n+54 <= name-sub 
    move NAME-1[n+54] to RIGHT-LABEL 
else 
    move spaces to RIGHT-LABEL 
endif 

같은이없는 경우 즉, 당신의 나머지를 위해 보호해야합니다 + 54는 적절한 공동 기호가 아닙니다.) 그리고 대소 문자를 섞어서 유감스럽게 생각합니다.하지만 오래 전에 COBOL을 작성하여 소문자로 사용했습니다. 내가 제대로 이해하고)

2

, 이것은 당신이

220-MOVE-RECORDS. 

     IF NAME-SUB >= 108 
      perform varing i from 1 to 54 
       MOVE NAME-1 (NAME-SUB) TO LEFT-LABEL 
       compute ip54 = i + 54 
       MOVE NAME-1 (ip54) TO RIGHT-LABEL 

       WRITE NAMELIST-RECORD-OUT 
       from DETAIL-LINE 
       AFTER ADVANCING 1 LINE 
      end-perform 

      MOVE SPACES TO DETAIL-LINE 
      MOVE ZERO TO NAME-SUB 
      PERFORM 300-WRITE-HEADING 

    END-IF. 

참고 원하는에 가까워 야 : 많은 코볼 컴파일러는 당신은 항상 오류가 모든 IO에 대한 검사를해야 소문자를

2

할 수 있습니다.

한 파일 -에 - 하나의 파일 아웃은 항상 같이 할 수 있습니다 : 첫 번째와

open input 
check status 
open output 
check status 
*priming read* 
process file until end 
close input 
check status 
close output 
check status 

process file 
do what is needed 
write output 
check status 
read input 
check staus 

은 "프라이밍 읽기"거래 :

open input 
check status 
open output 
check status 
process file until end 
close input 
check status 
close output 
check status 

process file 
read input 
check staus 
do what is needed 
write output 
check status 

더 나은이 같다 파일에 기록하십시오 (있는 경우). 메인 로직을 "혼동"시키거나 다른 곳에서 두 가지 유형의 "파일 끝"을 구별하지 않고도 "빈 파일"을 깔끔하게 처리 할 수 ​​있습니다. "프로세스 파일"의 마지막 부분에있는 읽기는 다소 구불 구불 한 "AT END/NOT AT END"를 제거합니다.

예를 들어, 테이블에 54 개 요소 만 필요합니다. 페이지의 "오른쪽"에 대한 레코드를 처리 할 때 "왼쪽"에서 첫 번째 레코드를 가져 와서 즉시 수행 할 수 있습니다.

테스트를 위해 리터럴이 아닌 88을 사용하십시오.

페이지 끝에 "제목"을 쓰지 마십시오. 더 이상 처리 할 레코드가없는 것처럼 머리글 뒤에 "빈 페이지"가 ​​생깁니다.인쇄 라인의 쓰기는 단락에있는 경우

것은, 그 단락은 108-와 54

의 초기 값을 갖는 "라인 카운트"로, 제목이 필요한지 여부 확인을 사용할 수 있습니다 요소 접근법을 사용하면 한 번에 한 페이지 씩 인쇄하면서 상단에 표제를 붙입니다.

데이터를 다른 것으로 설정하기 전에 데이터를 사용하지 않으면 초기 값으로 설정하지 않아도됩니다.

절차 코드에 대한 "최소 완전 정지/마침표"방식을 채택했습니다. 이는 적절한 최종 기간을 자체 라인에 두는 것이 어떻습니까?

PERFORM 220-MOVE-RECORDS. 

PERFORM 220-MOVE-RECORDS 
    . 

만 사용된다> = 또는 = < 값 논리적 최대 값을 초과 할 때. 너는 결코 할 수 없으므로 등식을 사용하십시오. 예, 초과하면 큰 팻 루프가 생깁니다. 그러나 예상치 못한 일이 발생했을 때 "일하는"것보다 낫습니다. 진단 메시지를 초과하여> 테스트하고 싶다면 괜찮습니다. 일부 컴파일러에서는 테이블 액세스의 "경계 검사"를 허용합니다. 사용하는 경우 추가 검사가 필요하지 않습니다.

1

작업 저장소 정의와 코드를 확인하는 것이 도움이되었습니다. 다른 하나없이 이해하기가 어렵습니다.

어쨌든 당신이 설명하는 것은 몇 가지 가능한 해결책이있는 상당히 "표준적인"종류의 문제입니다. 다음은 가능한 접근법의 개요입니다. 데이터 구조와

시작 ... 전문 스토리지 :

01 WS-PAGE-BUFFER. 
    02 WS-LINE OCCURS 54 TIMES. 
     03 WS-NAME PIC X(40) OCCURS 2 TIMES. 

상기 작업 기억 출력 한 페이지를 설명한다. 이 페이지에는 54 개의 행이 들어 있습니다. 각 줄에는 두 개의 이름이 있습니다. 당신은 몇 카운터 ...

01. 
    02 WS-LINE-CNTR  PIC S9(4) COMP. 
    02 WS-NAME-CNTR  PIC S9(4) COMP. 
필요 다음 두 문제

는 해결하기 :

  • 적절한 제목/트레일러
있는 페이지를 인쇄 적절한 순서
  • 에서 페이지를 작성

    이러한 문제를 해결할 때 염두에 두어야 할 점은 입력에 대해 여러 장면을 포함해야한다는 것입니다. 입력 없음, 입력이 정확하게 맞음 출력 페이지 중 일부는 이고 입력은 부분적으로 출력 페이지를 채 웁니다. 그래서 당신이 무엇을 하든지, 의 상황은 "자연스러운"방법으로 스스로를 분류해야합니다. 또한 일종의 사전/사후 앰블 인 것들이 있습니다 (예 : 초기화, 열린 파일, 닫는 파일 등).

    한가지 더 ... 항상은 캡처 오류로 입력/출력 파일과 파일 끝 조건에 대한 파일 상태를 선언합니다.아래의 알고리즘은 을 완료했다고 가정합니다 (파일 끝 상태는 일반적으로 '10'입니다)

    해골 알고리즘. 나는 "빈 공간"의 많음을 떠난

    MAINLINE 
        PERFORM INITIALIZE-PAGE 
        Open input file (check status etc...) 
        Open output file (check status etc...) 
        Read first line from file (check for errors/end of file etc...) 
        PERFORM UNTIL INPUT-FILE-STATUS NOT = ZERO /* read until eof/error 
         IF WS-LINE-CNTR = 54 AND WS-NAME-CNT = 2 /* check for full page. 
          PERFORM OUTPUT-PAGE 
         END-IF 
         ADD +1 TO WS-LINE-CNTR 
         IF WS-LINE-CNTR > 54 
          MOVE +1 TO WS-LINE-CNTR /* Start next column... 
          ADD +1 TO WS-NAME-CNTR /* Increment column 
         END-IF 
         MOVE input-record TO WS-NAME (WS-LINE-CNTR, WS-NAME-CNTR) 
         Read next line from input file 
        END-PERFORM 
    
        IF INPUT-FILE-STATUS = '10' AND WS-LINE-CNTR > ZERO 
         PERFORM OUTPUT-PAGE /* force the last page to print 
        END-IF 
    
        close input file 
        close output file 
    
        GOBACK /* done 
        . 
    
    INITIALIZE-PAGE. 
        MOVE SPACE TO WS-PAGE-BUFFER /* Blank page (ie. SPACES) 
        MOVE ZERO TO WS-LINE-CNTR  /* Top of page 
        MOVE +1 TO WS-NAME-CNTR  /* First column of page 
        . 
    
    OUTPUT-PAGE. 
        Ouput page headers... 
        PERFORM VARYING WS-LINE-CNTR FROM 1 BY 1 
           UNTIL WS-LINE-CNTR > 54 
         write WS-LINE (WS-LINE-CNTR) to output file (check status etc...) 
        END-PERORM 
        Output page trailers... 
        PERFORM INITIALIZE-PAGE /* Start a fresh page... 
        . 
    

    는 채워하고 난 당신이 뭘 하려는지 달성하기 위해 다른 더 우아한 방법이 인정되지만, 당신은 시작한다이.