이 글에서는 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) 기준 정렬도 같은 방식으로 손쉽게 구현할 수 있습니다.