[C언어 소스] 학생 성적 관리 프로그램 (학생 수 입력, 동적 메모리 할당, 파일 입출력)

안녕하세요. 언제나 휴일입니다.

이번 게시글은 학생 성적 관리 프로그램 C언어 소스 코드입니다.

관리할 학생 수는 프로그램 시작할 때 사용자가 결정합니다.

제공하는 기능은 학생 추가, 성적 입력, 삭제, 검색, 전체 보기입니다.

프로그램 끝날 때 학생 데이터를 파일에 기록하고 프로그램 시작할 때 파일의 내용을 로딩합니다.

#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>

#define MAX_NAME_LEN	20

enum Subject
{
    KOREAN, ENGLISH, MATH, MAX_SUBJECT
};
const char *stitle[MAX_SUBJECT] = { "국어","영어","수학" };

typedef struct _Student Student;
struct _Student
{
    int num;
    char name[MAX_NAME_LEN];
    int scores[MAX_SUBJECT];
};

#define DEF_FNAME    "data.stu"

int max_student;
Student *stues;

void Init();
void Run();
void Exit();
int main()
{
    Init();
    Run();
    Exit();
    return 0;
}
void Init()
{
    FILE *fp = fopen(DEF_FNAME, "r");
    if (fp)
    {
        fread(&max_student, sizeof(int), 1, fp);
        stues = (Student *)malloc(sizeof(Student)*max_student);
        fread(stues, sizeof(Student), max_student, fp);
        fclose(fp);
    }
    else
    {
        printf("관리할 학생 수:");
        max_student = getnum();
        stues = (Student *)malloc(sizeof(Student)*max_student);
        memset(stues,0, sizeof(Student)*max_student);
    }
}

int SelectMenu();
void AddStudent();
void AddScore();
void RemoveStudent();
void FindStudent();
void ViewAll();
void Run()
{
    int key = 0;
    while ((key = SelectMenu()) != 0)
    {
        switch (key)
        {
        case 1: AddStudent(); break;
        case 2: AddScore(); break;
        case 3: RemoveStudent(); break;
        case 4: FindStudent(); break;
        case 5: ViewAll(); break;
        default: printf("잘못 선택하였습니다.\n"); break;
        }
    }
}
int getnum();
int SelectMenu()
{
    printf("학생 성적 관리 프로그램 0:종료\n");
    printf("1:학생 추가 2:성적 입력 3: 삭제 4: 검색 5: 전체 보기\n");
    return getnum();
}
int getnum()
{
    int num = 0;
    if (scanf_s("%d", &num) == 0)
    {
        char buf[256];
        gets_s(buf, sizeof(buf));
    }
    return num;
}

void InitScore(Student *stu);
void AddStudent()
{
    int num = 0;
    Student *stu = 0;

    printf("추가할 학생 번호(1~%d):", max_student);
    num = getnum();
    if ((num < 1) || (num > max_student))
    {
        printf("범위를 벗어났습니다.\n");
        return;
    }

    stu = stues + (num - 1);
    if (stu->num)
    {
        printf("이미 자료가 있습니다.\n");
        return;
    }

    stu->num = num;
    printf("이름:");
    scanf_s("%s", stu->name, MAX_NAME_LEN);
    InitScore(stu);
}
void InitScore(Student *stu)
{
    int s = 0;
    for (s = 0; s < MAX_SUBJECT; s++)
    {
        stu->scores[s] = -1;
    }
}
void InputScore(Student *stu);
void AddScore()
{
    int num = 0;
    Student *stu = 0;

    printf("성적 입력할 학생 번호(1~%d):", max_student);
    num = getnum();
    if ((num < 1) || (num > max_student))
    {
        printf("범위를 벗어났습니다.\n");
        return;
    }

    stu = stues + (num - 1);
    if (stu->num == 0)
    {
        printf("추가하지 않은 학생 자료입니다. 먼저 학생 자료를 추가하세요.\n");
        return;
    }
    InputScore(stu);
}
void InputScore(Student *stu)
{
    int s = 0;
    int score = 0;
    for (s = 0; s<MAX_SUBJECT; s++)
    {
        printf("%s :", stitle[s]);
        score = getnum();
        if ((score < 0) || (score > 100))
        {
            score = -1;
        }
        stu->scores[s] = score;
    }
}

void RemoveStudent()
{
    int num = 0;
    Student *stu = 0;

    printf("삭제할 학생 번호(1~%d):", max_student);
    num = getnum();
    if ((num < 1) || (num > max_student))
    {
        printf("범위를 벗어났습니다.\n");
        return;
    }

    stu = stues + (num - 1);
    if (stu->num == 0)
    {
        printf("추가하지 않은 학생 자료입니다. 먼저 학생 자료를 추가하세요.\n");
        return;
    }
    memset(stu, 0, sizeof(Student));
}

void ViewStudent(Student *stu);
void FindStudent()
{
    int num = 0;
    Student *stu = 0;

    printf("검색할 학생 번호(1~%d):", max_student);
    num = getnum();
    if ((num < 1) || (num > max_student))
    {
        printf("범위를 벗어났습니다.\n");
        return;
    }

    stu = stues + (num - 1);
    if (stu->num == 0)
    {
        printf("추가하지 않은 학생 자료입니다. 먼저 학생 자료를 추가하세요.\n");
        return;
    }
    ViewStudent(stu);
}

void ViewScore(Student *stu);
void ViewStudent(Student *stu)
{
    printf("=== 번호:%d 이름:%s\n", stu->num, stu->name);
    ViewScore(stu);
}
void ViewScore(Student *stu)
{
    int s = 0;
    for (s = 0; s<MAX_SUBJECT; s++)
    {
        if (stu->scores[s] == -1)
        {
            printf("%s : 미입력\n", stitle[s]);
        }
        else
        {
            printf("%s :%d\n", stitle[s], stu->scores[s]);
        }
    }
}

void ViewAll()
{
    int i = 0;
    for (i = 0; i < max_student; i++)
    {
        if (stues[i].num)
        {
            ViewStudent(stues + i);
        }
    }
}
void Exit()
{
    FILE *fp = fopen(DEF_FNAME, "w");
    if (fp)
    {
        fwrite(&max_student, sizeof(int), 1, fp);
        fwrite(stues, sizeof(Student), max_student, fp);
        fclose(fp);
    }
    free(stues);
}