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

C/C++에서 디렉터리의 파일 목록을 가져오는 방법 완벽 정리

개요

표준 C++은 특정 디렉터리에 있는 파일 목록을 조회하는 기능을 기본적으로 제공하지 않습니다. 하지만 몇 가지 방법을 통해 이 작업을 손쉽게 수행할 수 있습니다. 가장 간단한 방법은 system() 함수를 사용해 운영체제의 셸 명령을 호출하는 것입니다.

방법 1: system() 함수로 ls 명령 실행하기

Linux나 macOS 환경이라면 system() 함수를 통해 ls 명령을 실행하여 파일 목록을 화면에 출력할 수 있습니다.

예제 코드

#include<iostream>
int main () {
   char command[50] = "ls -l";
   system(command);
   return 0;
}

실행 결과

위 코드를 실행하면 다음과 같은 출력을 확인할 수 있습니다.

-rwxrwxrwx 1 root root  9728 Feb 25 20:51 a.out
-rwxrwxrwx 1 root root   131 Feb 25 20:44 hello.cpp
-rwxrwxrwx 1 root root   243 Sep  7 13:09 hello.py
-rwxrwxrwx 1 root root 33198 Jan  7 11:42 hello.o
drwxrwxrwx 0 root root   512 Oct  1 21:40 hydeout
-rwxrwxrwx 1 root root    42 Oct 21 11:29 my_file.txt
-rwxrwxrwx 1 root root   527 Oct 21 11:29 watch.py

만약 Windows 환경이라면 ls 대신 dir 명령을 사용하면 동일하게 목록을 표시할 수 있습니다.

다만 이 방법은 명령어 실행 결과를 프로그램 내부에서 직접 활용하기 어렵고, 운영체제에 따라 동작이 달라진다는 단점이 있습니다.

방법 2: dirent.h 헤더 활용하기

더 유연하고 프로그래밍적으로 제어 가능한 방식을 원한다면 dirent 패키지를 사용하는 것이 좋습니다. POSIX 계열 시스템에서는 dirent.h가 기본 제공되며, Windows에서도 해당 패키지를 설치해 사용할 수 있습니다.

예제 코드

#include <iostream>
#include <dirent.h>
#include <sys/types.h>

using namespace std;
void list_dir(const char *path) {
   struct dirent *entry;
   DIR *dir = opendir(path);
   
   if (dir == NULL) {
      return;
   }
   while ((entry = readdir(dir)) != NULL) {
   cout << entry->d_name << endl;
   }
   closedir(dir);
}
int main() {
   list_dir("/home/username/Documents");
}

실행 결과

지정한 경로에 포함된 파일과 폴더 이름이 한 줄씩 출력됩니다.

a.out
hello.cpp
hello.py
hello.o
hydeout
my_file.txt
watch.py

이 방식은 opendir(), readdir(), closedir() 함수를 조합하여 디렉터리를 열고 항목을 하나씩 읽어온 뒤 닫는 구조로 되어 있어, 파일 이름을 문자열로 받아 원하는 로직에 자유롭게 활용할 수 있다는 장점이 있습니다.

참고: C++17의 std::filesystem 활용하기

C++17부터는 표준 라이브러리에 <filesystem>이 포함되어 더 이상 외부 의존성 없이 디렉터리 탐색이 가능합니다. 최신 컴파일러를 사용한다면 아래와 같이 작성할 수 있습니다.

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main() {
   for (const auto& entry : fs::directory_iterator("/home/username/Documents")) {
       std::cout << entry.path().filename() << std::endl;
   }
   return 0;
}

컴파일 시 GCC라면 -std=c++17 옵션을 지정해야 정상적으로 빌드됩니다. 크로스 플랫폼 호환성과 타입 안전성을 고려한다면 std::filesystem을 사용하는 것이 가장 권장되는 방법입니다.