말랑말랑제리스타일

c언어 구조체로 학생 관리 콘솔 프로그램 만들기 본문

직접만든프로그램 소개

c언어 구조체로 학생 관리 콘솔 프로그램 만들기

제리제리 2023. 6. 26. 09:27

 C언어에서 구조체를 이용해 학생 관리 프로그램을 만들어봅시다. 콘솔 프로그래밍으로 학생 배열을 만들어 진행할 예정이며, 기능은 입력, 전체 출력, 번호를 이용한 삭제, 번호를 이용한 조회 이렇게 네 가지 기능으로 된 프로그램입니다.

C언어 학생 관리 시스템 프로그램 전체 틀 구성

프로그램의 전체 흐름을 구성해 봅시다.

일단 학생 정보에 대한 구조체가 필요할 것이고 main 함수에서는 콘솔 프로그램이기 때문에 계속 반복되도록 while문을 걸어줘야겠죠.

그리고 C언어에서 동적으로 메모리 할당할 수도 있지만 학생 관리 콘솔 프로그램을 만드는 실습을 하는 단계에서 malloc 등의 동적 할당을 배웠을 확률이 낮기 때문에 define으로 최대 학생 수와 학생 이름의 최대 길이를 미리 정의해 두겠습니다.

 

#include <stdio.h>
#define MAX_NAME_LEN 100
#define MAX_STUDENT 100

struct student {
  int snum;
  char sname[MAX_NAME_LEN];
}; // 학생 구조체

int main(void) {
  struct student students[MAX_STUDENT]; // 학생 구조체 배열
  int num_of_student = 0; // 입력된 학생 수
  while (1) {
  	//여기서 프로그램 흐름
  }
  return 0;
}

define으로 학생 이름의 최대 길이를 100으로 잡아주고 최대 학생 수도 100으로 잡아줍니다.

학생 구조체는 기본적으로 학생번호와 이름을 가집니다. 물론 더 추가할 수도 있겠죠.

main 함수에서는 student라는 학생 구조체 배열을 선언해 주고 최대 길이만큼 학생을 추가할 수 있게 해 줍니다.

num_of_student는 최초에 입력된 학생이 없기 때문에 0으로 잡아줍니다.

자 이제 메뉴를 출력해 봅시다.

C언어 학생 관리 시스템 메뉴 출력 부분 만들기

자 while문 내부에 네 개의 메뉴(학생 입력, 학생 리스트 출력, 학생 번호 검색, 학생 삭제)와 프로그램 종료기능을 넣어줍시다.

#include <stdio.h>
#define MAX_NAME_LEN 100
#define MAX_STUDENT 100

struct student {
  int snum;
  char sname[MAX_NAME_LEN];
};

int main(void) {
  struct student students[MAX_STUDENT];
  int num_of_student = 0;
  while (1) {
    int menu = 0;
    printf("=====메뉴=====\n");
    printf("1. 학생 입력\n");
    printf("2. 학생 리스트 출력\n");
    printf("3. 학생 번호 검색\n");
    printf("4. 학생 삭제\n");
    printf("5. 프로그램 종료\n");
    printf("메뉴 번호를 입력하세요 : ");
    scanf("%d", &menu);
    if (menu < 1 || menu > 5) {
      printf("잘못된 입력입니다.\n");
      continue;
    }
    if(menu == 5){
      return 0;
    }
  }
  return 0;
}

프로그램 종료를 포함해 학생 관리 시스템에서 필요한 다섯 개의 메뉴를 출력해 주고 메뉴 번호를 입력받습니다.

이 입력받은 내용을 저장하기 위해 menu라는 int형 변수를 사용하고 만약 없는 메뉴 번호를 입력했다면 다시 입력받습니다.

그리고 menu가 5인 경우 학생 관리 프로그램 종료를 위해 return 0로 main 함수를 끝내줍니다.

물론 break로 while문만 끝내줄 수도 있습니다.

 

자 여기까지 C언어 콘솔로 구현하는 학생 관리 프로그램의 기본 틀이 완성되었습니다.

이제 각각의 기능을 만들어보겠습니다.

C언어 학생 관리 프로그램 세부 기능 작성

자 앞서 말했듯이 이 C언어 학생 관리 프로그램은 4개의 기능이 있습니다.

학생 입력, 학생 리스트 출력, 학생 번호 검색, 학생 삭제 기능이죠.

이 4가지 핵심 기능을 간단하게 구현해 보겠습니다.

C언어 학생 관리 프로그램 학생 입력 기능

학생 입력은 생각보다 간단합니다. students 배열의 num_of_student 번지에 학생의 정보를 입력하면 되죠.

예를 들어 최초에는 num_of_student가 0이기 때문에 입력을 하면 students[0]에 입력이 됩니다.

그리고 학생 수가 늘었으니 num_of_student가 1 증가해야겠죠.

간단히 이 내용을 C언어 소스로 구현해 봅시다.

    else if (menu == 1) {
      printf("===학생 입력===\n");
      printf("학생 번호: ");
      scanf("%d", &students[num_of_student].snum);
      printf("학생 이름: ");
      scanf("%s", &students[num_of_student].sname);
      num_of_student++;
    }

메뉴에서 1을 선택하면 학생 입력이라는 메뉴 명이 나오고 학생 번호를 입력하라고 나옵니다.

정수형으로 입력받아 students[0] 번의 snum에 학생 번호를 저장하고 학생 이름을 입력하면 0번 학생의 이름을 입력할 수 있습니다.

그리고 num_of_student를 1 증가시켜서 이후에는 1번 학생을 입력할 수 있게 해 주죠.

C언어 학생 관리 프로그램 학생 리스트 출력 기능

다음은 학생 리스트를 출력하는 기능을 만들어봅시다.

더 간단하죠. 0번 학생부터 num_of_student - 1번 학생까지 출력해 주면 됩니다.

왜 1을 빼냐면 학생 수가 2면 0번과 1번까지 총 두 명의 학생이 입력되어 있기 때문이죠.

자 이 부분도 C 언어 소스로 구현해 봅시다.

    if (menu == 2) {
      printf("===학생 리스트 출력===\n");
      for (int i = 0; i < num_of_student; i++) {
        printf("학생 번호 : %d 학생 이름 : %s\n", students[i].snum,
               students[i].sname);
      }
    }

엄청 간단하죠. for 문을 이용해서 i라는 변수를 0번부터 num_of_student보다 작을 때까지 순회하니 당연히 num_of_student - 1까지 순회하게 되는 거죠.

순회하면서 학생 번호와 학생 이름을 출력해 주는 겁니다.

C언어 학생 관리 프로그램 검색 기능

자 여기부터 살짝 까다로워질 수 있습니다.

일단 학생 번호를 검색받아서 이 학생을 학생 리스트에서 조회해 이름을 출력해 주는 기능인데요.

일단 학생 번호를 snum이라는 내부에 새로운 변수를 선언해서 입력받고 학생 리스트를 for문으로 순회하면서 같은 번호를 가진 학생을 출력해 주는 거죠.

그리고 출력하고 나면 더 이상 다른 학생을 확인하지 않고 메뉴로 돌아갑니다.

    if (menu == 3) {
      int snum;
      printf("===학생 번호 검색===\n");
      printf("학생 번호: ");
      scanf("%d", &snum);
      for (int i = 0; i < num_of_student; i++) {
        if (students[i].snum == snum) {
          printf("학생 번호 : %d 학생 이름 : %s\n", students[i].snum,
                 students[i].sname);
          break;
        }
      }
    }

자 만약 존재하는 경우는 별게 없습니다.

하지만 번호에 해당하는 학생이 존재하지 않는다면 아무것도 출력하지 않고 메뉴로 돌아갈 겁니다.

자 여기서 번호에 해당하는 학생이 출력하지 않는 경우 존재하지 않는다는 문구를 한번 추가해 주겠습니다.

    if (menu == 3) {
      int snum;
      int exists = 0;
      printf("===학생 번호 검색===\n");
      printf("학생 번호: ");
      scanf("%d", &snum);
      for (int i = 0; i < num_of_student; i++) {
        if (students[i].snum == snum) {
          printf("학생 번호 : %d 학생 이름 : %s\n", students[i].snum,
                 students[i].sname);
          exists++;
          break;
        }
      }
      if (exists == 0) {
        printf("학생번호 %d 이 존재하지 않습니다.", snum);
      }
    }

exists라는 변수를 하나 만들어주고 0으로 초기화해줍니다.

그리고 학생을 찾은 경우 exist에 1을 더해서 exists가 더 이상 0이 아니게 만들어주죠.

이후 for문에서 벗어났을 때 exists 변수가 0이 아닌 경우 넘어가고 0인 경우 번호에 해당되는 학생을 찾지 못했기 때문에 학생 번호에 해당되는 학생이 존재하지 않는다고 띄워줍니다.

C언어 학생 관리 프로그램 번호로 학생 삭제하는 기능

자 이제 우리의 C언어 학생 관리 프로그램에서 학생 번호로 해당되는 학생을 삭제하는 기능을 구현해 봅시다.

일단 앞에 조회 기능을 복사해 줍니다. 찾아야 삭제할 수 있기 때문이죠.

바꿀 부분을 보면 일단 메뉴를 4로 바꿔주고 메뉴 타이틀을 학생 삭제로 바꿔줍시다.

그리고 해당되는 학생을 찾은 경우 for문을 이용해서 그다음 학생부터 한 칸씩 앞으로 당겨줍니다.

그리고 삭제된 학생 번호와 이름을 알려주면서 다시 메뉴로 돌아가는 거죠.

존재하지 않는 경우의 처리는 조회와 동일하기 때문에 따로 손댈 필요는 없습니다.

    if (menu == 4) {
      int snum;
      int exists = 0;
      printf("===학생 삭제===\n");
      printf("학생 번호: ");
      scanf("%d", &snum);
      for (int i = 0; i < num_of_student; i++) {
        if (students[i].snum == snum) {
          printf("학생 번호 : %d 학생 이름 : %s 이 삭제됩니다.\n",
                 students[i].snum, students[i].sname);
          for (int j = i; j < num_of_student; j++) {
            students[j] = students[j + 1];
          }
          num_of_student--;
          exists++;
          break;
        }
      }
      if (exists == 0) {
        printf("학생번호 %d 이 존재하지 않습니다.\n", snum);
      }
    }

삭제 for 문을 좀 더 상세하게 설명드리겠습니다.

예를 들어서 학생이 4명 입력되어 있다고 봅시다.

1 2 3 4
홍구 공실이 C대장 망고

이렇게 되어있다면 num_of_student는 총 4명이겠죠.

그리고 실제 배열에 있는 항목 번호를 추가해 보면 아래와 같습니다.

students[0] students[1] students[2] students[3]
1 2 3 4
홍구 공실이 C대장 망고

여기서 2번 공실이를 상제 한다고 생각합시다.

for문을 돌다가 2번 공실이를 students[1]에서 찾게 됩니다. 이때 i는 1이 되겠죠.

그럼 j는 2부터 3(num of student -1)까지 반복하면서 한 칸씩 당겨줍니다.

즉, 순서대로 바뀌는 학생 배열을 확인해 보면

students[0] students[1] students[2] students[3]
1 3 3 4
홍구 C대장 C대장 망고
students[0] students[1] students[2] students[3]
1 3 4 4
홍구 C대장 망고 망고

이렇게 되는 거죠.

그리고 학생 수는 3이 됩니다.

마지막에 망고라는 4번 학생이 중복으로 있죠.

하지만 이미 학생 수를 3으로 줄였기 때문에 이 마지막 망고 학생에 접근할 일은 없어집니다.

입력을 하더라도 students[3]에 덮어쓰게 될 예정이니 상관없고, 전체 리스트를 뽑더라도 학생 수가 3이다 보니 students[2]의 망고까지만 출력될 거고, 조회나 삭제를 하더라도 students[2]의 망고 학생까지만 확인을 할 거 기 때문에 놔둬도 문제 될 게 없죠.

 

C언어 콘솔 학생 관리 프로그램 전체 소스

자 여기까지 C언어로 만들어본 학생 관리 프로그램이었습니다. 전체 소스는 아래와 같습니다.

#include <stdio.h>
#define MAX_NAME_LEN 100
#define MAX_STUDENT 100

struct student {
  int snum;
  char sname[MAX_NAME_LEN];
};

int main(void) {
  struct student students[MAX_STUDENT];
  int num_of_student = 0;
  while (1) {
    int menu = 0;
    printf("=====메뉴=====\n");
    printf("1. 학생 입력\n");
    printf("2. 학생 리스트 출력\n");
    printf("3. 학생 번호 검색\n");
    printf("4. 학생 삭제\n");
    printf("5. 프로그램 종료\n");
    printf("메뉴 번호를 입력하세요 : ");
    scanf("%d", &menu);
    if (menu < 1 || menu > 5) {
      printf("잘못된 입력입니다.\n");
      continue;
    }
    if (menu == 5) {
      return 0;
    } else if (menu == 1) {
      printf("===학생 입력===\n");
      printf("학생 번호: ");
      scanf("%d", &students[num_of_student].snum);
      printf("학생 이름: ");
      scanf("%s", &students[num_of_student].sname);
      num_of_student++;
    } else if (menu == 2) {
      printf("===학생 리스트 출력===\n");
      for (int i = 0; i < num_of_student; i++) {
        printf("학생 번호 : %d 학생 이름 : %s\n", students[i].snum,
               students[i].sname);
      }
    } else if (menu == 3) {
      int snum;
      int exists = 0;
      printf("===학생 번호 검색===\n");
      printf("학생 번호: ");
      scanf("%d", &snum);
      for (int i = 0; i < num_of_student; i++) {
        if (students[i].snum == snum) {
          printf("학생 번호 : %d 학생 이름 : %s\n", students[i].snum,
                 students[i].sname);
          exists++;
          break;
        }
      }
      if (exists == 0) {
        printf("학생번호 %d 이 존재하지 않습니다.", snum);
      }
    } else if (menu == 4) {
      int snum;
      int exists = 0;
      printf("===학생 삭제===\n");
      printf("학생 번호: ");
      scanf("%d", &snum);
      for (int i = 0; i < num_of_student; i++) {
        if (students[i].snum == snum) {
          printf("학생 번호 : %d 학생 이름 : %s 이 삭제됩니다.\n",
                 students[i].snum, students[i].sname);
          for (int j = i; j < num_of_student; j++) {
            students[j] = students[j + 1];
          }
          num_of_student--;
          exists++;
          break;
        }
      }
      if (exists == 0) {
        printf("학생번호 %d 이 존재하지 않습니다.\n", snum);
      }
    }
  }
  return 0;
}

이 프로그램은 당연히 완벽하지는 않죠.

좀 더 완벽하게 만들기 위해서는 DB나 파일을 연결해서 내용을 저장하고 불러오는 기능을 추가해 줄 수 있고, 학생 번호 입력하는 부분에서 이미 존재하는 학생 번호라면 입력을 막아줄 수도 있겠죠.

당연히 학생 명이 100자가 넘어가는 경우나 학생 수가 100명을 넘어가는 경우를 대비해서 높은 수를 두거나 배열 메모리를 동적으로 할당할 수도 있습니다.

C언어 콘솔 학생 관리프로그램 캡처
C언어 콘솔 학생 관리프로그램 캡처

하지만 C언어로 학생 관리 프로그램을 구현해 보는 예제나 과제 수준의 프로그램이라면 이 정도면 충분히 만족하겠다 싶을 정도로 소스를 짜봤습니다.

 

반응형
Comments