본문 바로가기

카테고리 없음

[Pascal] 학생 정보 관리(Student Info Manage)

학교 과제로 학생 정보를 관리해주는 Program을 만들었습니다.

노트북에만 내버려두기에 너무 아쉬워서 블로그에 남겨보려 합니다. :D

 

1. Program 요구사항

여러 학생의 과목별 점수를 입력하고, 이를 합산하여 Sorting 하는 Pascal program을 작성하라.

 

  • 한 학생의 data는 학번, 이름, 과목별 성적(3개 이상)으로 하라.
  • Quick sorting algorithm을 이용하라.
  • Sub program을 두 개 이상 정의하여 작성하라.
  • EOF, EOLN을 이용하여, 임의의 학생수 및 과목수에 대해 처리할 수 있도록 하라.(확장성이 좋도록 작성하라)

 

2. Program code 개요

1) Main program

사용자에게 보여줄 interface를 출력해주고, 사용자의 입력에 따라 각 기능을 수행하는 Main program입니다.

프로그램은 아래의 순서로 총 6가지의 기능을 가지고 있습니다.

 

  • directory에 존재하는 file list를 출력
  • 새로운 file 생성
  • 지정된 file에 data 추가 
  • 지정된 file 읽기
  • 성적순으로 학생정보 출력
  • program 종료

case 구문을 통해서 쉽게 구현할 수 있었습니다.

 

2) Print File List

Directory에 어떤 file들이 있는지 저장하는 fileList.txt를 열어서 안의 내용을 출력합니다.

만약 fileList.txt에 아무런 data가 저장되어 있지 않다면, 생성된 file이 존재하지 않는 것이므로 새로운 file을 먼저 생성해줄 것을 사용자에게 요청합니다.

 

3) Write Info

사용자로부터 data를 입력 받아 새로운 학생 object를 생성합니다.

생성된 객체는 txt file에 곧바로 저장됩니다.

마지막에 학생의 이름을 consol에 출력해서 작업이 완료되었음을 알려줍니다.

 

해당 function이 실행되면 fileList.txt에 생성된 file의 이름이 저장됩니다.

만약 program을 처음 실행한 것이라면, fileList.txt를 생성한 뒤에 file의 이름을 저장합니다.

 

4) Get Student List

지정된 txt file을 열어서 학생들의 정보를 가져옵니다.

해당 정보는 array로 저장되어 반환됩니다.

 

5) Get Line

지정된 txt file을 열고 한 줄단위로 읽을 때 사용하는 function입니다.

 

6) Print Student Line

학생 객체 배열을 parameter로 받아와서 이를 출력해주는 function입니다.

 

7) Quick Sort

학생들의 평점을 기준으로 정렬을 수행하는 function으로 내림차순으로 정렬됩니다.

 

3. Source code

1) MainProgram의 excutable section

program StudentInfoManage;

    ...
    
    begin
        menuNum := 0;
        repeat
            writeln('*******************MENU*******************');
            writeln('[1] Print file list');
            writeln('[2] New File');
            writeln('[3] Append info');
            writeln('[4] Read file');
            writeln('[5] Academic ranking');
            writeln('[0] Exit');
            writeln('*******************END********************');
            write('Choose one: ');
            readln(menuNum);
            case (menuNum) of
                (* print file list *)
                1 : begin
                    fileName := 'fileList.txt';
                    PrintFileList(fileName);
                end;
                (* create new file *)
                2 : begin
                    (* list up new file's name *)
                    fileName := 'fileList.txt';	
                    assign(listFp, fileName);
                    if FileExists(fileName) then begin 
                        append(listFp);	
                    end
                    else begin 
                        rewrite(listFp);
                    end;

                    writeln;
                    write('Enter file name you want to create: ');
                    readln(fileName);

                    writeln(listFp, fileName);
                    close(listFp);
                    writeln('Now input data at new file. Pleas press enter to keep going');
                    readln;

                    (* input data at new file *)
                    assign(f, fileName);
                    rewrite(f);

                    WriteInfo(f);

                    writeln('File ', fileName, ' was extended if all went ok.');
                    writeln;
                    close(f);
                end;
                (* eidt file of student info *)
                3 : begin
                    writeln;
                    write('Enter file name you want to edit: ');
                    readln(editFileName);

                    // editFileName의 이름으로 파일이 존재하면				
                    if FileExists(editFileName) then begin
                        assign(f, editFileName);
                        append(f);

                        WriteInfo(f);

                        writeln('File ', fileName, ' was extended if all went ok.');
                        close(f);
                        writeln;				
                        end
                    else begin
                        writeln('There is no file');
                        writeln('Pleas enter valied file name');
                        writeln;
                        end;
                    end;
                (* read selectd fild *)
                4 : begin
                    writeln;
                    write('Enter you want to read file of student info: ');
                    readln(fileName);

                    // fileName의 이름으로 파일이 존재하면	
                    if FileExists(fileName) then begin
                        assign(f, fileName);
                        reset(f);
                        studentList := GetStudentList(f);

                        printStudentList(studentList);

                        writeln('File ', fileName, ' was extended if all went ok.');
                        close(f);
                        writeln;				
                        end
                    else begin
                        writeln('There is no file');
                        writeln('Pleas enter valied file name');
                        writeln;
                        end;
                    end;
                5 : begin

                    writeln;
                    write('Enter file name for sorting: ');
                    readln(fileName);
                    writeln;

                    // fileName의 이름으로 파일이 존재하면	
                    if FileExists(fileName) then begin
                        assign(f, fileName);
                        reset(f);
                        studentList := GetStudentList(f);
                        studentList := QuickSort(MAX, studentList);
                        writeln('----------Ranking----------');

                        printStudentList(studentList);

                        writeln('---------------------------');
                        writeln('File ', fileName, ' was extended if all went ok.');
                        close(f);
                        writeln;				
                        end
                    else begin
                        writeln('There is no file');
                        writeln('Pleas enter valied file name');
                        writeln;
                        end;

                end;
                (* for exiting program *)
                0 : begin
                    writeln('Press Enter to end');
                    readln;
                end;
                otherwise begin
                    writeln('Invalide number try again');
                    writeln('');
                end;
            end;
        until menuNum = 0;
    end.

 

2) Print File List

// file list 출력
procedure PrintFileList(fName : String);

    procedure PrintList(var listFp : text);
    begin
        while not eof(listFp) do
        begin
            read(listFp, fileName);
            writeln(fileName);
            if eoln(listFp) then readln(listFp);
        end;
    end;
    
    begin
        writeln;
        writeln('----------LIST----------');

        // fileList.txt의 이름으로 파일이 존재하면					
        if FileExists(fileName) then begin
            assign(fp, fName);
            reset(fp);
            PrintList(fp);
            close(fp);
        end
        else begin
            writeln('Please create any file first');
        end;

        writeln('------------------------');
        writeln;
    end;

 

3) Write Info

// student info 입력
procedure WriteInfo(var fi: text);
    begin		
        write('Input student number : ');
        readln(studentNew.number);
        writeln(fi, studentNew.number);
        write('Input student name : ');
        readln(studentNew.name);
        writeln(fi, studentNew.name);
        writeln('Input student grade below(korean, math, english)');
        readln(studentNew.korean);
        writeln(fi, studentNew.korean);
        readln(studentNew.math);
        writeln(fi, studentNew.math);
        readln(studentNew.english);
        writeln(fi, studentNew.english);
        studentNew.average := (studentNew.korean + studentNew.math + studentNew.english) / 3;

        writeln(fi, studentNew.average);
        writeln(fi);
        writeln;

        writeln('hello ', studentNew.name);
    end;

 

4) Get Student List

// student info 읽고 배열로 반환
function GetStudentList(var fo: text): RecordList;
    begin		
        i := 1;
        while not eof(fo) do
        begin
            studentTemp.number:= GetLine(fo);
            studentTemp.name := GetLine(fo);

            // convert string to integer
            val(GetLine(fo), studentTemp.korean, CODE);
            val(GetLine(fo), studentTemp.math, CODE);
            val(GetLine(fo), studentTemp.english, CODE);

            // convert string to real
            val(GetLine(fo), studentTemp.average, CODE);
            if CODE<>0 then
            begin
                writeln('an error has occured');
                halt(1);
            end;

            listTemp[i] := studentTemp;
            i := i + 1;

            // 줄바꿈 넘김
            readln(fo);
        end;

        GetStudentList := listTemp;
    end;

 

5) Get Line

// txt 파일에서 한 줄 읽기
function GetLine(var glFo: text): string;
    begin
        strCombine:= '';
        while not eoln(glFo) do
        begin
            read(glFo, strTemp);
            strCombine:= strCombine+ strTemp;
        end;
        readln(glFo, strTemp);
        GetLine:= strCombine;
    end;

 

6) Print Student Line

// 학생 정보 출력
procedure printStudentList(sList : RecordList);
    begin
        for i:=1 to MAX do begin
            if not (studentList[i].name = '') then begin
                writeln('Name: ', sList[i].name);
                writeln('Number: ', sList[i].number);
                writeln('Average: ', sList[i].average:2:2);
                writeln('Grade(korean, math, english): ', sList[i].korean, ' ', sList[i].math, ' ', sList[i].english);
                readln;
            end;
        end;
    end;

 

7) Quick Sort

// 성적순(내림차순)으로 정렬
function QuickSort(size: integer; var sList: RecordList): RecordList;
    // 재귀호출
    procedure QuickSortRecur(left, right: integer);
        var
            splitpt: integer;

        function Split(left, right: integer): integer;
            var
                // pl: pivot 기준 왼쪽 인덱스
                // pr: pivot 기준 오른쪽 인덱스
                pl, pr: integer;

                // 좌,우 부분 배열을 만드는 기준
                p: real;
            procedure swap(var x, y: StudentRecord);
                var
                    t: StudentRecord;
                begin
                    t := x;
                    x := y;
                    y := t;
                end;
            begin
                p := sList[left].average;
                pl := left+1;
                pr := right;

                while pl <= pr do begin
                    // 좌측은 pivot 보다 큰 값들의 부분 배열. pivot 보다 작은 값 탐색
                    while (pl <= right) and (sList[pl].average >= p) do
                        pl := pl + 1;
                    // pivot 보다 큰 값 탐색
                    while (pr > left) and (sList[pr].average < p) do
                        pr := pr - 1;
                    // pl < pr = true이면 부분 배열 형성이 완료되지 않음
                    // 탐색이 끝난 요소들 간의 교환 수행
                    if pl < pr then
                        swap(sList[pl], sList[pr]);
                end;
                // n차 정렬이 완료되면, pivot을 배열의 중앙으로 이동
                swap(sList[left], sList[pr]);
                // 분할된 배열의 시작점 반환
                Split := pr;
            end;
        begin
            if left < right then begin
                // 분할된 배열의 시작점 대입
                splitpt := Split(left, right);
                // 분할된 배열들 sorting
                QuickSortRecur(left, splitpt-1);
                QuickSortRecur(splitpt+1, right);
            end
        end;
    begin
        QuickSortRecur(1, size);
        QuickSort := sList;
    end;

 

8) 전체 코드

program StudentInfoManage;
	Uses sysutils;
	const
		MAX = 10;
	type
		StudentRecord = record
				number, name: string;
				korean, math, english: integer;
				average: real;
		end;
		// StudentRecord형 배열 자료형
		RecordList = array[1..MAX] of StudentRecord;
	var 
		i, menuNum, CODE: integer;
		
		fileName: string;
		editFileName: string;
		strCombine, strTemp: string;
		
		f, fp: text;
		
		studentNew, studentTemp: StudentRecord;
		studentList, listTemp: RecordList;
	
	// file list 출력
	procedure PrintFileList(fName : String);
		procedure PrintList(var listFp : text);
		begin
			while not eof(listFp) do
			begin
				read(listFp, fileName);
				writeln(fileName);
				if eoln(listFp) then readln(listFp);
			end;
		end;
	begin
		writeln;
		writeln('----------LIST----------');
		
		// fileList.txt의 이름으로 파일이 존재하면					
		if FileExists(fileName) then begin
			assign(fp, fName);
			reset(fp);
			PrintList(fp);
			close(fp);
		end
		else begin
			writeln('Please create any file first');
		end;
		
		writeln('------------------------');
		writeln;
	end;	

	// student info 입력
	procedure WriteInfo(var fi: text);
	begin		
		write('Input student number : ');
		readln(studentNew.number);
		writeln(fi, studentNew.number);
		write('Input student name : ');
		readln(studentNew.name);
		writeln(fi, studentNew.name);
		writeln('Input student grade below(korean, math, english)');
		readln(studentNew.korean);
		writeln(fi, studentNew.korean);
		readln(studentNew.math);
		writeln(fi, studentNew.math);
		readln(studentNew.english);
		writeln(fi, studentNew.english);
		studentNew.average := (studentNew.korean + studentNew.math + studentNew.english) / 3;
		writeln(fi, studentNew.average);
		writeln(fi);
		writeln;
		
		writeln('hello ', studentNew.name);
	end;
	
	// txt 파일에서 한 줄 읽기
	function GetLine(var glFo: text): string;
	begin
		strCombine:= '';
		while not eoln(glFo) do
		begin
			read(glFo, strTemp);
			strCombine:= strCombine+ strTemp;
		end;
		readln(glFo, strTemp);
		GetLine:= strCombine;
	end;
	
	// student info 읽고 배열로 반환
	function GetStudentList(var fo: text): RecordList;
	begin		
		i := 1;
		while not eof(fo) do
		begin
			studentTemp.number:= GetLine(fo);
			studentTemp.name := GetLine(fo);
			
			// convert string to integer
			val(GetLine(fo), studentTemp.korean, CODE);
			val(GetLine(fo), studentTemp.math, CODE);
			val(GetLine(fo), studentTemp.english, CODE);
			
			// convert string to real
			val(GetLine(fo), studentTemp.average, CODE);
			if CODE<>0 then
			begin
				writeln('an error has occured');
				halt(1);
			end;

			listTemp[i] := studentTemp;
			i := i + 1;
			
			// 줄바꿈 넘김
			readln(fo);
		end;
        
		GetStudentList := listTemp;
	end;
	
	// 학생 정보 출력
	procedure printStudentList(sList : RecordList);
	begin
		for i:=1 to MAX do begin
			if not (studentList[i].name = '') then begin
				writeln('Name: ', sList[i].name);
				writeln('Number: ', sList[i].number);
				writeln('Average: ', sList[i].average:2:2);
				writeln('Grade(korean, math, english): ', sList[i].korean, ' ', sList[i].math, ' ', sList[i].english);
				readln;
			end;
		end;
	end;

	// 성적순(내림차순)으로 정렬
	function QuickSort(size: integer; var sList: RecordList): RecordList;
		// 재귀호출
		procedure QuickSortRecur(left, right: integer);
			var
				splitpt: integer;
				
			function Split(left, right: integer): integer;
				var
					// pl: pivot 기준 왼쪽 인덱스
					// pr: pivot 기준 오른쪽 인덱스
					pl, pr: integer;
					
					// 좌,우 부분 배열을 만드는 기준
					p: real;
				procedure swap(var x, y: StudentRecord);
					var
						t: StudentRecord;
					begin
						t := x;
						x := y;
						y := t;
					end;
				begin
					p := sList[left].average;
					pl := left+1;
					pr := right;
					
					while pl <= pr do begin
						// 좌측은 pivot 보다 큰 값들의 부분 배열. pivot 보다 작은 값 탐색
						while (pl <= right) and (sList[pl].average >= p) do
							pl := pl + 1;
						// pivot 보다 큰 값 탐색
						while (pr > left) and (sList[pr].average < p) do
							pr := pr - 1;
						// pl < pr = true이면 부분 배열 형성이 완료되지 않음
						// 탐색이 끝난 요소들 간의 교환 수행
						if pl < pr then
							swap(sList[pl], sList[pr]);
					end;
					// n차 정렬이 완료되면, pivot을 배열의 중앙으로 이동
					swap(sList[left], sList[pr]);
					// 분할된 배열의 시작점 반환
					Split := pr;
				end;
			begin
				if left < right then begin
					// 분할된 배열의 시작점 대입
					splitpt := Split(left, right);
					// 분할된 배열들 sorting
					QuickSortRecur(left, splitpt-1);
					QuickSortRecur(splitpt+1, right);
				end
			end;
		begin
			QuickSortRecur(1, size);
			QuickSort := sList;
		end;
	
	begin
        menuNum := 0;
        repeat
            writeln('*******************MENU*******************');
            writeln('[1] Print file list');
            writeln('[2] New File');
            writeln('[3] Append info');
            writeln('[4] Read file');
            writeln('[5] Academic ranking');
            writeln('[0] Exit');
            writeln('*******************END********************');
            write('Choose one: ');
            readln(menuNum);
            case (menuNum) of
                (* print file list *)
                1 : begin
                    fileName := 'fileList.txt';
                    PrintFileList(fileName);
                end;
                (* create new file *)
                2 : begin
                    (* list up new file's name *)
                    fileName := 'fileList.txt';	
                    assign(fp, fileName);
                    if FileExists(fileName) then begin 
                        append(fp);	
                    end
                    else begin 
                        rewrite(fp);
                    end;

                    writeln;
                    write('Enter file name you want to create: ');
                    readln(fileName);

                    writeln(fp, fileName);
                    close(fp);
                    writeln('Now input data at new file. Pleas press enter to keep going');
                    readln;

                    (* input data at new file *)
                    assign(f, fileName);
                    rewrite(f);
                    WriteInfo(f);
                    writeln('File ', fileName, ' was extended if all went ok.');
                    writeln;
                    close(f);
                end;
                (* eidt file of student info *)
                3 : begin
                    writeln;
                    write('Enter file name you want to edit: ');
                    readln(editFileName);

                    // editFileName의 이름으로 파일이 존재하면				
                    if FileExists(editFileName) then begin
                        assign(f, editFileName);
                        append(f);
                        WriteInfo(f);
                        writeln('File ', fileName, ' was extended if all went ok.');
                        close(f);
                        writeln;				
                        end
                    else begin
                        writeln('There is no file');
                        writeln('Pleas enter valied file name');
                        writeln;
                        end;
                    end;
                (* read selectd fild *)
                4 : begin
                    writeln;
                    write('Enter you want to read file of student info: ');
                    readln(fileName);

                    // fileName의 이름으로 파일이 존재하면	
                    if FileExists(fileName) then begin
                        assign(f, fileName);
                        reset(f);
                        studentList := GetStudentList(f);
                        printStudentList(studentList);
                        writeln('File ', fileName, ' was extended if all went ok.');
                        close(f);
                        writeln;				
                        end
                    else begin
                        writeln('There is no file');
                        writeln('Pleas enter valied file name');
                        writeln;
                        end;
                    end;
                5 : begin

                    writeln;
                    write('Enter file name for sorting: ');
                    readln(fileName);
                    writeln;

                    // fileName의 이름으로 파일이 존재하면	
                    if FileExists(fileName) then begin
                        assign(f, fileName);
                        reset(f);
                        studentList := GetStudentList(f);
                        studentList := QuickSort(MAX, studentList);
                        writeln('----------Ranking----------');
                        printStudentList(studentList);
                        writeln('---------------------------');
                        writeln('File ', fileName, ' was extended if all went ok.');
                        close(f);
                        writeln;				
                        end
                    else begin
                        writeln('There is no file');
                        writeln('Pleas enter valied file name');
                        writeln;
                        end;

                end;
                (* for exiting program *)
                0 : begin
                    writeln('Press Enter to end');
                    readln;
                end;
                otherwise begin
                    writeln('Invalide number try again');
                    writeln('');
                end;
            end;
        until menuNum = 0;
	end.

 

4. 실행결과

1) 실행화면

 

interface 출력화면

 

2) 새로운 file 생성 및 flie list 출력

 

file이 없는 상태에서 file list 출력

 

새로운 file 생성

 

file을 생성한 직후의 file list 출력

 

3) file에 내용 추가 및 data.txt 내용 출력

 

data.txt file에 data 추가

 

data.txt fild 읽기

 

4) 평균을 기준으로 성적순 정렬 후 출력

 

정렬되기 전의 학생들 정보 #1

 

정렬되기 전의 학생들 정보 #2

 

정렬된 후의 학생들 정보 #1

 

정렬된 후의 학생들 정보 #2

 

5) 그 외 부가기능

 

유효하지 않은 메뉴를 선택

 

새로 추가된 파일들을 표시하는 Print file list

 

유효하지 않은 파일 이름을 입력한 Append info

 

유효하지 않은 파일 이름을 입력한 Read file

 

유효하지 않은 파일 이름을 입력한 Academic ranking

 

 

 

6) Program 종료

 

 

5. 마무리

게시글을 작성하면서 program의 가독성이 다소 떨어지는 느낌을 받았습니다.

당시에는 ​처음 학습한 언어로 이 정도 만들었으면 잘했단 느낌을 받았는데 말입니다ㅎ..

여유가 된다면 가독성이 좋게 renewal도 해보고, file 삭제, file의 특정 부분 삭제 등의 새로운 기능도 개발해보고 싶네요.