#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해도 무방하다.