StartprogrammingusingObjectPascal:AppendingStudentMarksProgram

From 흡혈양파의 번역工房
Jump to: navigation, search

학생 성적 추가 프로그램

Program AppendMarks;

{$mode objfpc}{$H+}

uses
    {$IFDEF UNIX}{$IFDEF UseCThreads}
    cthreads,
    {$ENDIF}{$ENDIF}
    Classes, SysUtils
    { you can add units after this };

var
    F: file of Byte;
    Mark: Byte;
begin
    AssignFile(F, 'marks.dat');
    if FileExists('marks.dat') then
    begin
        FileMode:= 2; // Open file for read/write
        Reset(F); // open file
        Seek(F, FileSize(F)); // Go to beyond last record
        Writeln('Please input students marks, write 0 to exit');

        repeat
            Write('Input a mark: ');
            Readln(Mark);
            if Mark <> 0 then // Don't write 0 value in disk
                Write(F, Mark);
        until Mark = 0;
        CloseFile(F);
    end
    else
        Writeln('File marks.dat not found');

    Write('Press enter key to close..');
    Readln;
end.

이 프로그램을 실행하고 새 레코드를 입력하고 나서 덧붙인 데이터를 보기 위해 다시 실행할 수 있습니다.

참고로 파일에 기록을 목적으로 파일을 열기 위해 Rewrite 프로시저 대신 Reset 프로시저를 사용하였습니다. Rewrite는 기존의 파일의 모든 데이터를 지우고, 파일이 존재하지 않는다면 빈 파일을 만들지만, Reset은 내용을 지우지 않고 기존의 파일을 열기만 할 수 있습니다.

또한 읽기/쓰기 접근 모드를 위해 파일을 열 필요가 있다는 것을 나타내기 위해 FileMode 변수에 2를 할당했습니다. FileMode의 0은 읽기 전용, 1은 쓰기 전용, 2(기본)는 읽기/쓰기를 의미합니다.

        FileMode:= 2; // Open file for read/write
        Reset(F); // open file

Reset은 첫번째 레코드에 읽기/쓰기 포인터를 놓고, 이러한 이유로 파일에 바로 기록을 시작하면 이전 레코드에 덮어쓰게 되기 때문에, 파일의 끝으로 읽기/쓰기 포인터를 이동하기 위해 Seek 프로시저를 사용했습니다. Seek는 임의 접근 파일에서만 사용할 수 있습니다.

Seek 프로시저로 존재하지 않는 레코드 위치에 접근하려 한다면 (예를 들어, 50 레코드만 있는데 100번째 레코드에 접근하려 한다면), 오류를 만나게 될 것입니다.

파일의 현재 레코드 갯수를 되돌리는 FileSize 함수도 사용했습니다. 파일의 끝으로 건너뛰기 위해 Seek 프로시저와 함께 사용했습니다.

Seek(F, FileSize(F)); // Go to beyond last record

참고로 이 예제는 기존의 학생 성적 파일이 있을 경우에 사용할 수 있습니다. 만약 그렇지 않다면, 새 파일을 만들 수 있도록 Rewrite를 사용하는 처음 프로그램(학생 성적 저장하기)을 실행해야 합니다.

다음 예제를 통해 우리가 해낸 바와 같이, 파일의 존재 유무에 따라 두 가지 방식(ResetRewrite)을 혼용할 수 있습니다.