c언어 구조체 파일입출력 읽기

조회수 2046회

안녕하세요! 파일입출력을 통해서 학생정보를 저장하고 프로그램을 끄고 다시 켜서 학생 정보 불러오기를 하면 구조체를 읽어 올 수 있도록 하고 싶은데 오류가 납니다,, 혹시 무엇이 잘못되었고 어떻게 고쳐야하는지 알려주세요ㅠㅠ


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#define MAX 50

typedef struct student
{
 char Name[10];
 int Age;
 int Class;
 int Number;
 char Gender[10];
}Student;

int menu();
void SetStudent(Student* St, int* Number);
void ShowStudent(Student* St);
void FineStudent(Student* Student_List[]);
void ShowGrade(Student* Student_List[], int grade);

int StudentCount = 0;

void main()
{
 Student* Student_List[MAX];
 int ch = 0;

 FILE* f = fopen("StudentFile.txt", "w");

 while (1)
 {
  switch (menu())
  {
  case 1: //학생 등록
   if (StudentCount + 1 >= 50)
   {
    printf("학생정원(%d명)이 모두 찼습니다.\n");
    system("pause");
    break;
   }
   Student_List[StudentCount] = (Student*)malloc(sizeof(Student));
   SetStudent(Student_List[StudentCount], &StudentCount);
   break;

  case 2: //학생목록(번호순)
   system("cls");
   for (int i = 0; i < StudentCount; i++)
    ShowStudent(Student_List[i]);
   system("pause");
   break;

  case 3: //학생목록(학년순)
   system("cls");
   ShowGrade(Student_List, 1);
   ShowGrade(Student_List, 2);
   ShowGrade(Student_List, 3);
   system("Pause");
   break;

  case 4: //학년 검색
   system("cls");
   printf("검색할 학년을 입력하세요: ");
   scanf("%d", &ch);

   while (1)
   {
    if (ch > 3 || ch < 1)
    {
     printf("1~3학년까지 존재합니다. 다시 입력해주세요\n");
     system("Pause");
     ch = 0;
     system("cls");
     printf("학년 입력 : ");
     scanf("%d", &ch);
    }
    else
    {
     ShowGrade(Student_List, ch);
     break;
    }
   }


   system("Pause");

   break;

  case 5: //학생 검색
   system("cls");
   FineStudent(Student_List);
   system("Pause");
   break;

  case 6: //마지막 학생 삭제
   if (StudentCount <= 0)
   {
    printf("삭제할 데이터가 없습니다.");
    system("pause");
   }
   else
   {
    printf("%s 학생의 정보가 삭제되었습니다.", Student_List[StudentCount - 1]->Name);
    free(Student_List[StudentCount - 1]);
    StudentCount--;
    system("pause");
   }
   break;

  case 7: //학생 전체 삭제
   if (StudentCount <= 0)
   {
    printf("삭제할 데이터가 없습니다.\n");
    system("pause");
   }
   else
   {
    for (int i = 0; i < StudentCount; i++)
     free(Student_List[i]);

    StudentCount = 0;

    printf("생기부 초기화\n");
    system("pause");
   }
   break;

  case 8: //학생정보 저장
   system("cls");
   fprintf(f, "등록된 학생수 : %d\n\n", StudentCount);
   for (int i = 0; i < StudentCount; i++)
    fprintf(f, "%s %d %s %d\n", Student_List[i]->Name, Student_List[i]->Age, Student_List[i]->Gender, Student_List[i]->Class);
   fclose(f);
   printf("저장이 완료되었습니다. \n");
   system("Pause");
   break;
  case 9: //학생정보 불러오기
   f = fopen("StudentFile.txt", "r");
   if (f == NULL)
    printf("가져올 데이터가 없습니다, \n");
   else
   {
    int i = StudentCount;
    while (!feof(f))
    {
     fscanf(f, "%s", Student_List[i]->Name);
     fscanf(f, "%d", &Student_List[i]->Age);
     fscanf(f, "%s", Student_List[i]->Gender);
     fscanf(f, "%d", &Student_List[i]->Class);
     i++;
    }
    StudentCount += i;
    fclose(f);
    printf("불러오기가 완료되었습니다. \n");
    system("Pause");
   }
   break;

  case 10: //종료
   for (int i = 0; i < StudentCount; i++)
   {
    printf("%s학생 동적할당 해제 완료\n", Student_List[i]->Name);
    free(Student_List[i]);
   }
   return;
  }
 }
}

int menu()
{
 int ch = 0;

 system("cls");
 printf("=====학생관리프로그램=====(총 인원 : %d)\n", StudentCount);
 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", &ch);

 return ch;
}

void ShowStudent(Student* St)
{
 printf("======%s학생(%d번)======\n", St->Name, St->Number);
 printf("나이 : %d,  성별 : %s,  학년 : %d\n", St->Age, St->Gender, St->Class);
 printf("======================\n");
}
void SetStudent(Student* St, int* Number)
{
 system("cls");
 St->Number = ++(*Number);
 printf("======%d번 학생======\n", St->Number);
 printf("이름 입력 : ");
 scanf("%s", St->Name);
 printf("나이 입력 : ");
 scanf("%d", &St->Age);
 printf("성별 입력 : ");
 scanf("%s", St->Gender);
 printf("학년 입력 : ");
 scanf("%d", &St->Class);
 while (1)
 {
  if (St->Class < 1 || St->Class > 3)
  {
   printf("1~3학년까지 존재합니다. 다시 입력해주세요\n");
   St->Class = { 0 };
   printf("학년 입력 : ");
   scanf("%d", &St->Class);
  }
  else
   break;
 }


}

void FineStudent(Student* Student_List[])
{
 char fine_name[20] = { 0 };
 printf("검색할 이름 입력 : ");
 scanf("%s", fine_name);
 for (int i = 0; i < StudentCount; i++)
 {
  if (strcmp(fine_name, Student_List[i]->Name) == 0)
  {
   ShowStudent(Student_List[i]);
  }
  else
  {
   printf("해당 학생이 없습니다.");
   system("pause");
  }

 }
}

void ShowGrade(Student* Student_List[], int grade)
{
 printf("┏──────────%d 학년──────────┓\n", grade);
 for (int i = 0; i < StudentCount; i++)
  if (Student_List[i]->Class == grade)
   ShowStudent(Student_List[i]);
 printf("┗──────────────────────────┛\n");
}
  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 파일 열고 닫는 함수, 파일에 값 저장하는 함수, 파일에서 값 읽는 함수, 메모리 동적 할당과 해제 함수 등이 모두 사용된 프로그램이네요.

    처음 배우는 분들에게는 하나하나가 어려운 것들인데, 그것들을 모두 사용하는 프로그램이다보니 더 어려우실 것 같네요.

    아래 코드 참고하세요.

    • 코드
    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<stdlib.h>
    #include<Windows.h>
    #define MAX 50
    
    typedef struct student
    {
        char Name[10];
        int Age;
        int Class;
        int Number;
        char Gender[10];
    }Student;
    
    int menu();
    void SetStudent(Student* St, int* Number);
    void ShowStudent(Student* St);
    void FineStudent(Student* Student_List[]);
    void ShowGrade(Student* Student_List[], int grade);
    
    int StudentCount = 0;
    
    void main()
    {
        Student* Student_List[MAX];
        int ch = 0;
    
        //FILE* f = fopen("StudentFile.txt", "w"); // 오류 5, 심각한 오류, w로 열게되면 파일 내용 모두 삭제됨, 위치 아래로 이동
    
        while (1)
        {
            switch (menu())
            {
            case 1: //학생 등록
                if (StudentCount + 1 > 50) // 오류 1: >= 을 >로 수정
                {
                    printf("학생정원(%d명)이 모두 찼습니다.\n", MAX); // 오류 4
                    system("pause");
                    break;
                }
                Student_List[StudentCount] = (Student*)malloc(sizeof(Student));
                SetStudent(Student_List[StudentCount], &StudentCount);
                break;
    
            case 2: //학생목록(번호순)
                system("cls");
                for (int i = 0; i < StudentCount; i++)
                    ShowStudent(Student_List[i]);
                system("pause");
                break;
    
            case 3: //학생목록(학년순)
                system("cls");
                ShowGrade(Student_List, 1);
                ShowGrade(Student_List, 2);
                ShowGrade(Student_List, 3);
                system("Pause");
                break;
    
            case 4: //학년 검색
                system("cls");
                printf("검색할 학년을 입력하세요: ");
                scanf("%d", &ch);
    
                while (1)
                {
                    if (ch > 3 || ch < 1)
                    {
                        printf("1~3학년까지 존재합니다. 다시 입력해주세요\n");
                        system("Pause");
                        ch = 0;
                        system("cls");
                        printf("학년 입력 : ");
                        scanf("%d", &ch);
                    }
                    else
                    {
                        ShowGrade(Student_List, ch);
                        break;
                    }
                }
    
                system("Pause");
    
                break;
    
            case 5: //학생 검색
                system("cls");
                FineStudent(Student_List);
                system("Pause");
                break;
    
            case 6: //마지막 학생 삭제
                if (StudentCount <= 0)
                {
                    printf("삭제할 데이터가 없습니다.");
                    system("pause");
                }
                else
                {
                    printf("%s 학생의 정보가 삭제되었습니다.", Student_List[StudentCount - 1]->Name);
                    free(Student_List[StudentCount - 1]);
                    StudentCount--;
                    system("pause");
                }
                break;
    
            case 7: //학생 전체 삭제
                if (StudentCount <= 0)
                {
                    printf("삭제할 데이터가 없습니다.\n");
                    system("pause");
                }
                else
                {
                    for (int i = 0; i < StudentCount; i++)
                        free(Student_List[i]);
    
                    StudentCount = 0;
    
                    printf("생기부 초기화\n");
                    system("pause");
                }
                break;
    
            case 8: //학생정보 저장
                system("cls");
                FILE* f = fopen("StudentFile.txt", "w");
                fprintf(f, "등록된 학생수 : %d\n\n", StudentCount);
                for (int i = 0; i < StudentCount; i++)
                    fprintf(f, "%s %d %s %d %d\n", Student_List[i]->Name, Student_List[i]->Age, Student_List[i]->Gender, Student_List[i]->Class, Student_List[i]->Number);
                fclose(f);
                printf("저장이 완료되었습니다. \n");
                system("Pause");
                break;
            case 9: //학생정보 불러오기
                f = fopen("StudentFile.txt", "r");
                if (f == NULL)
                    printf("가져올 데이터가 없습니다, \n");
                else
                {
                    // 오류 6: 이 아래로 대폭 수정
    
                    for (int i = 0; i < StudentCount; i++)
                        free(Student_List[i]);
    
                    fscanf(f, "등록된 학생수 : %d\n\n", &StudentCount);
    
                    for (int i = 0; i < StudentCount; i++)
                    {
                        Student_List[i] = (Student*)malloc(sizeof(Student));
                        fscanf(f, "%s %d %s %d %d\n", Student_List[i]->Name, &Student_List[i]->Age, Student_List[i]->Gender, &Student_List[i]->Class, &Student_List[i]->Number);
    
                    }
    
                    //int i = StudentCount;
                    //while (!feof(f))
                    //{
                    //    fscanf(f, "%s", Student_List[i]->Name);
                    //    fscanf(f, "%d", &Student_List[i]->Age);
                    //    fscanf(f, "%s", Student_List[i]->Gender);
                    //    fscanf(f, "%d", &Student_List[i]->Class);
                    //    i++;
                    //}
                    //StudentCount += i;
    
                    fclose(f);
                    printf("불러오기가 완료되었습니다. \n");
                    system("Pause");
                }
                break;
    
            case 10: //종료
                for (int i = 0; i < StudentCount; i++)
                {
                    printf("%s학생 동적할당 해제 완료\n", Student_List[i]->Name);
                    free(Student_List[i]);
                }
                return;
            }
        }
    }
    
    int menu()
    {
        int ch = 0;
    
        system("cls");
        printf("=====학생관리프로그램=====(총 인원 : %d)\n", StudentCount);
        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", &ch);
    
        return ch;
    }
    
    void ShowStudent(Student* St)
    {
        printf("======%s학생(%d번)======\n", St->Name, St->Number);
        printf("나이 : %d,  성별 : %s,  학년 : %d\n", St->Age, St->Gender, St->Class);
        printf("======================\n");
    }
    
    void SetStudent(Student* St, int* Number)
    {
        system("cls");
        St->Number = ++(*Number);
        printf("======%d번 학생======\n", St->Number);
        printf("이름 입력 : ");
        scanf("%s", St->Name);
        printf("나이 입력 : ");
        scanf("%d", &St->Age);
        printf("성별 입력 : ");
        scanf("%s", St->Gender);
        printf("학년 입력 : ");
        scanf("%d", &St->Class);
        while (1)
        {
            if (St->Class < 1 || St->Class > 3)
            {
                printf("1~3학년까지 존재합니다. 다시 입력해주세요\n");
                //St->Class = { 0 }; // 오류 2, 불필요 하므로 삭제
                printf("학년 입력 : ");
                scanf("%d", &St->Class);
            }
            else
                break;
        }
    }
    
    void FineStudent(Student* Student_List[])
    {
        char fine_name[20] = { 0 };
        printf("검색할 이름 입력 : ");
        scanf("%s", fine_name);
        for (int i = 0; i < StudentCount; i++)
        {
            if (strcmp(fine_name, Student_List[i]->Name) == 0)
            {
                ShowStudent(Student_List[i]);
                return; // 오류3, 추가함
            }
            else
            {
                printf("해당 학생이 없습니다.");
                system("pause");
            }
        }
    }
    
    void ShowGrade(Student* Student_List[], int grade)
    {
        printf("┏──────────%d 학년──────────┓\n", grade);
        for (int i = 0; i < StudentCount; i++)
            if (Student_List[i]->Class == grade)
                ShowStudent(Student_List[i]);
        printf("┗──────────────────────────┛\n");
    }
    
    • 결과

    이미지

    이미지

    이미지

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)