디렉토리에 포함된 파일 목록을 확인해야 하는 경우가 종종 있습니다. C와 C++에서는 dirent.h 헤더 파일에서 제공하는 POSIX 표준 함수들을 활용하면 손쉽게 구현할 수 있습니다. 이 글에서는 실제 동작하는 예제 코드와 함께 그 원리를 자세히 살펴보겠습니다.
핵심 함수 소개
디렉토리 탐색에는 크게 세 가지 함수가 사용됩니다.
- opendir(): 지정한 경로의 디렉토리를 열고, 이후 작업에 사용할 DIR 타입의 스트림 포인터를 반환합니다.
- readdir(): 열려 있는 디렉토리에서 항목(파일 또는 하위 디렉토리)을 하나씩 읽어 dirent 구조체 포인터로 반환합니다. 더 이상 읽을 항목이 없으면 NULL을 반환합니다.
- closedir(): 열려 있던 디렉토리 스트림을 닫아 시스템 리소스를 해제합니다.
알고리즘
시작
DIR 타입의 포인터 dr을 선언한다.
dirent 구조체의 포인터 en을 선언한다.
opendir() 함수를 호출하여 현재 디렉토리를 연다.
dr = opendir(".") 형태로 포인터를 초기화한다.
만약 dr이 NULL이 아니라면
while ((en = readdir(dr)) != NULL)
en->d_name으로 각 파일 이름을 출력한다.
closedir() 함수를 호출하여 디렉토리를 닫는다.
종료C++ 예제 코드
다음은 iostream과 dirent.h를 사용해 현재 디렉토리의 모든 파일 이름을 출력하는 C++ 코드입니다.
#include <iostream>
#include <dirent.h>
#include <sys/types.h>
using namespace std;
int main(void) {
DIR *dr;
struct dirent *en;
dr = opendir("."); // 현재 디렉토리 열기
if (dr != NULL) {
while ((en = readdir(dr)) != NULL) {
cout << "\n" << en->d_name; // 파일 및 디렉토리 이름 출력
}
closedir(dr); // 디렉토리 닫기
}
return 0;
}실행 결과
BINSEARC.C BINTREE (1).C BINTREE.C BTREE.C BUBBLE.C c.txt file3.txt HEAP.C HEAPSORT.C HLINKLST.C INSERTIO.C LINKLIST.C LINKLST.C LLIST1.C players.cpp PolarRect.cpp QUEUE.C
C 예제 코드
동일한 로직은 순수 C 언어로도 구현할 수 있습니다. printf만 사용하면 되므로 코드가 더욱 간결해집니다.
#include <stdio.h>
#include <dirent.h>
int main(void) {
DIR *dr;
struct dirent *en;
dr = opendir("."); // 현재 디렉토리 열기
if (dr != NULL) {
while ((en = readdir(dr)) != NULL) {
printf("%s\n", en->d_name); // 파일 및 디렉토리 이름 출력
}
closedir(dr); // 디렉토리 닫기
}
return 0;
}실행 결과
BINSEARC.C BINTREE (1).C BINTREE.C BTREE.C BUBBLE.C c.txt file3.txt HEAP.C HEAPSORT.C HLINKLST.C INSERTIO.C LINKLIST.C LINKLST.C LLIST1.C
참고 사항
출력 결과를 보면 .(현재 디렉토리)와 ..(상위 디렉토리) 같은 특수 항목도 함께 나타날 수 있습니다. 이를 제외하고 싶다면 반복문 안에서 strcmp(en->d_name, ".") 조건으로 필터링하면 됩니다. 또한 dirent.h는 POSIX 계열(Linux, macOS 등) 환경의 헤더이므로, Windows에서 네이티브로 개발할 때는 Win32 API의 FindFirstFile/FindNextFile 함수나 C++17의 <filesystem> 라이브러리를 사용하는 것이 좋습니다.