Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 언어로 학생 기록을 구조체에 저장하고 이름순으로 정렬하는 방법

이 글에서는 student_id(학번), student_name(이름), student_percentage(백분율) 정보를 담고 있는 학생 기록을 구조체(structure)에 저장한 뒤, 이름을 기준으로 오름차순 정렬하는 C 프로그램을 다룹니다.

문제 이해하기

먼저 예시를 통해 문제를 살펴보겠습니다.

입력 — 학생 기록:

{ student_id = 1, student_name = Nupur,  student_percentage = 98 },
{ student_id = 2, student_name = Akash,  student_percentage = 75 },
{ student_id = 3, student_name = Yash,   student_percentage = 62 },
{ student_id = 4, student_name = Jyoti,  student_percentage = 87 },
{ student_id = 5, student_name = Ramlal, student_percentage = 80 }

출력 — 이름순으로 정렬된 학생 기록:

{ student_id = 2, student_name = Akash,  student_percentage = 75 },
{ student_id = 4, student_name = Jyoti,  student_percentage = 87 },
{ student_id = 1, student_name = Nupur,  student_percentage = 98 },
{ student_id = 5, student_name = Ramlal, student_percentage = 80 },
{ student_id = 3, student_name = Yash,   student_percentage = 62 }

Akash → Jyoti → Nupur → Ramlal → Yash 순서로, 알파벳 순(사전순)으로 데이터가 재배치된 것을 확인할 수 있습니다.

해결 접근 방법

문제를 해결하는 절차는 다음과 같습니다.

1. 학생 정보를 담을 구조체(struct Student)를 정의합니다.
2. 표준 라이브러리의 qsort() 함수를 사용해 배열을 정렬합니다.
3. qsort()에 전달할 비교 함수(comparator)를 직접 정의하며, 이 안에서 strcmp()를 호출해 두 학생의 이름을 사전순으로 비교합니다.

strcmp()는 두 문자열을 비교하여 첫 번째 문자열이 더 작으면 음수, 같으면 0, 더 크면 양수를 반환하므로, 그대로 반환값으로 사용하면 이름 기준 오름차순 정렬이 완성됩니다.

예제 코드

학생 기록을 구조체로 저장하고 이름순으로 정렬하는 C 프로그램

// 학생 기록을 구조체로 저장하고 이름순으로 정렬하는 C 프로그램
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student {
    int student_id;
    char* student_name;
    int student_percentage;
};

// 두 학생의 이름을 비교하는 비교 함수
int comparator(const void* s1, const void* s2) {
    return strcmp(((struct Student*)s1)->student_name,
                  ((struct Student*)s2)->student_name);
}

int main() {
    int n = 5;
    struct Student arr[n];

    // 학생 1
    arr[0].student_id = 1;
    arr[0].student_name = "Nupur";
    arr[0].student_percentage = 98;

    // 학생 2
    arr[1].student_id = 2;
    arr[1].student_name = "Akash";
    arr[1].student_percentage = 75;

    // 학생 3
    arr[2].student_id = 3;
    arr[2].student_name = "Yash";
    arr[2].student_percentage = 62;

    // 학생 4
    arr[3].student_id = 4;
    arr[3].student_name = "Jyoti";
    arr[3].student_percentage = 87;

    // 학생 5
    arr[4].student_id = 5;
    arr[4].student_name = "Ramlal";
    arr[4].student_percentage = 80;

    printf("정렬되지 않은 학생 기록:\n");
    for (int i = 0; i < n; i++) {
        printf("Id = %d, Name = %s, Percentage = %d \n",
               arr[i].student_id, arr[i].student_name, arr[i].student_percentage);
    }

    // 이름 기준으로 정렬 수행
    qsort(arr, n, sizeof(struct Student), comparator);

    printf("\n\n이름순으로 정렬된 학생 기록:\n");
    for (int i = 0; i < n; i++) {
        printf("Id = %d, Name = %s, Percentage = %d \n",
               arr[i].student_id, arr[i].student_name, arr[i].student_percentage);
    }

    return 0;
}

실행 결과

정렬되지 않은 학생 기록:
Id = 1, Name = Nupur, Percentage = 98
Id = 2, Name = Akash, Percentage = 75
Id = 3, Name = Yash, Percentage = 62
Id = 4, Name = Jyoti, Percentage = 87
Id = 5, Name = Ramlal, Percentage = 80

이름순으로 정렬된 학생 기록:
Id = 2, Name = Akash, Percentage = 75
Id = 4, Name = Jyoti, Percentage = 87
Id = 1, Name = Nupur, Percentage = 98
Id = 5, Name = Ramlal, Percentage = 80
Id = 3, Name = Yash, Percentage = 62

핵심 포인트 정리

- qsort()의 네 번째 인자로 전달되는 비교 함수는 반드시 const void* 형태의 매개변수 두 개를 받아야 하며, 내부에서 원래 자료형으로 형 변환(casting)해 사용합니다.
- 문자열 비교에는 strcmp()가 가장 간편하며, 대소문자가 섞인 데이터라면 필요에 따라 strcasecmp()(POSIX) 또는 직접 구현한 대소문자 무시 비교 함수를 활용할 수 있습니다.
- 정렬 기준을 바꾸고 싶다면 비교 함수만 수정하면 됩니다. 예를 들어 학번(student_id)이나 백분율(student_percentage) 기준 정렬도 같은 방식으로 손쉽게 구현할 수 있습니다.