반응형
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#define MAX 50
#define TRUE 1

typedef struct StudentInfo
{
    int Number;
    char Name[10];
    int Age;
    char Gender[10];
    int Grade;
}StudentInfo;

int SetStudent(StudentInfo* student, int count)
{
    student->Number = ++count;
    printf("====%d번 학생====", student->Number);
    printf("\n이름 입력 : ");
    scanf("%s", student->Name);
    printf("\n나이 입력 : ");
    scanf("%d", &student->Age);
    printf("\n성별 입력 : ");
    scanf("%s", student->Gender);
    printf("\n학년 입력<1~3> : ");
    scanf("%d", &student->Grade);

    return count;
}

void ShowStudent(StudentInfo* student)
{
    printf("====%s학생<%d번>====\n", student->Name, student->Number);
    printf("나이 : %d, 성별 : %s, 학년 : %d\n", student->Age, student->Gender, student->Grade);
    printf("==========\n");
}

void ShowStudentByGrade(StudentInfo* studentArr[], int grade)
{
    printf("========%d 학년 \n", grade);
    for (int i = 0; studentArr[i] != NULL; i++)
    	if (studentArr[i]->Grade == grade)
        	ShowStudent(studentArr[i]);

    printf("==========\n");
}

void SearchStudentByGrade(StudentInfo* studentArr[])
{
    int grade = 0;
    printf("학년 입력 : ");
    scanf("%d", &grade);

    system("cls");
    if (grade > 0 && grade <= 3)
    	ShowStudentByGrade(studentArr, grade);
}

void SearchStudentByName(StudentInfo* studentArr[])
{
    char name[10] = { 0 };
    printf("이름 입력 : ");
    scanf("%s", name);

    system("cls");
    for (int i = 0; studentArr[i] != NULL; i++)
    	if (strcmp(studentArr[i]->Name, name) == 0)
    		ShowStudent(studentArr[i]);
}

void Save(StudentInfo* studentArr[])
{
    FILE* file = fopen("Students.txt", "w");

    for (int i = 0; studentArr[i] != NULL && i < MAX; i++)
    	fprintf(file, "%s %d %s %d\n", studentArr[i]->Name, studentArr[i]->Age,
    	studentArr[i]->Gender, studentArr[i]->Grade);

    fclose(file);
}

//포인터로 반환해도 좋지만, return으로 반환을 우선으로 생각한다.
int Load(StudentInfo* studentArr[], int count)
{
    if (count + 1 >= MAX)
    {
    	printf("학생목록을 더이상 불러올 수 없습니다.");
    	system("pause");
    	return;
    }

    FILE* file = fopen("Students.txt", "r");
    if (file == NULL)
    {
    	printf("해당 파일이 존재하지 않습니다.");
    }
    else
    {
    	for (; count < MAX; count++)
        {
            studentArr[count] = (StudentInfo*)malloc(sizeof(StudentInfo));
            studentArr[count]->Number = count + 1;
            int eof = fscanf(file, "%s%d%s%d", studentArr[count]->Name, &studentArr[count]->Age,
            studentArr[count]->Gender, &studentArr[count]->Grade);
            if (eof == EOF)
            {
                free(studentArr[count]);
                studentArr[count] = NULL;
                break;
            }
        }

        fclose(file);

        return count;
    }
}

void main()
{
    StudentInfo* studentArr[MAX] = { 0 };
    int count = 0;
    while (TRUE)
    {
    	system("cls");
        int label = 0;

        printf("====학생관리프로그램====(total : %d)\n", count);
        printf("  1. 학생 등록\n");
        printf("  2. 학생 목록<번호순>\n");
        printf("  3. 학생 목록<학년순>\n");
        printf("  4. 학년 검색\n");
        printf("  5. 학생 검색\n");
        printf("  6. 마지막 학생 삭제\n");
        printf("  7. 학생 전체 삭제\n");
        printf("  8. 학색 목록 저장하기\n");
        printf("  9. 학색 목록 불러오기\n");
        printf("  10. 종료\n");
        printf("입력 : ");
        scanf("%d", &label);

        system("cls");
        switch (label)
        {
        case 1:
            if (count + 1 >= MAX)
            {
            	printf("정원(50명) 초과");
                system("pause");
                break;
            }

            studentArr[count] = (StudentInfo*)malloc(sizeof(StudentInfo));
            count = SetStudent(studentArr[count], count);
            break;
        case 2:
            for (int i = 0; i < count; i++)
                ShowStudent(studentArr[i]);

            system("pause");
            break;
        case 3:
            for (int i = 0; i < 3; i++)
                ShowStudentByGrade(studentArr, i + 1);

            system("pause");
            break;
        case 4:
            SearchStudentByGrade(studentArr);
            system("pause");
            break;
        case 5:
            SearchStudentByName(studentArr);
            system("pause");
            break;
        case 6:
            if (count > 0)
            {
            	count--;
                free(studentArr[count]);
                studentArr[count] = NULL;
            }
            break;
        case 7:
            count = 0;
            for (int i = 0; studentArr[i] != NULL; i++)
            {
            	free(studentArr[i]);
                studentArr[i] = NULL;
            }
            break;
        case 8:
            if (count > 0)
                Save(studentArr);
            break;
        case 9:
            count = Load(studentArr, count);
            break;
        case 10:
            return;
        }
    }
}

  ※ SetSudent함수 : Grade 값이 범위 안(1학년~3학년) 사이에 들지 않는 오입력이 일어날 수 있으므로 필요하면 while문으로 범위 안에 들어올 때까지 계속 값을 요구하는 코드를 넣을수도 있다.

  ※ SetStudent함수, Load 함수 : count 인수를 포인터로 받을수도 있지만 이런 경우엔 포인터로 인수를 받기보단 return 값을 먼저 생각해서 작성한다.

  ※case 10 (종료 Label) : 프로그램이 종료되면 동적 할당이 자동으로 반환되지만, 해제 후 return해도 무방하다.

반응형

'Stack > C' 카테고리의 다른 글

C 파일 입출력  (0) 2021.08.24
C 구조체, 구조체 포인터  (0) 2021.08.22
C 동적할당  (0) 2021.08.22
C 포인터, 배열  (0) 2021.08.22

+ Recent posts