メニュー
検索
言語
タグ
フォルダ以下のアイテム一覧を取得する関数 (listdir)
総合評価: - 作成日: 2025-10-04
コメント:
Linuxでメモリリークテスト済み。
Windows/Linuxで動作確認済み。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <dirent.h>
#endif
void
listdir_free_list(char **list) {
for (char **p = list; *p; p++) {
free(*p);
}
free(list);
}
static char *
listdir_strdup(const char *s) {
size_t len = strlen(s);
char *p = malloc(len+1);
if (!p) {
return NULL;
}
strcpy(p, s);
return p;
}
/**
* dir_path以下のアイテムを文字列のポインタ配列として返す。
*/
char **
listdir(const char *dir_path) {
if (!dir_path) {
return NULL;
}
char **list = NULL;
size_t list_len = 0;
size_t list_capa = 4;
size_t byte = sizeof(char*);
size_t size = byte * list_capa + byte;
list = malloc(size);
if (!list) {
return NULL;
}
list[list_len] = NULL;
#undef resize
#define resize() {\
if (list_len >= list_capa) {\
list_capa *= 2;\
size = byte * list_capa + byte;\
char **tmp = realloc(list, size);\
if (!tmp) {\
listdir_free_list(list);\
return NULL;\
}\
list = tmp;\
}\
}\
#ifdef _WIN32
char pattern[MAX_PATH];
snprintf(pattern, sizeof pattern, "%s\\*", dir_path);
WIN32_FIND_DATAA fd;
HANDLE h = FindFirstFileA(pattern, &fd);
if (h == INVALID_HANDLE_VALUE) {
listdir_free_list(list);
return NULL;
}
do {
if (!strcmp(fd.cFileName, ".") ||
!strcmp(fd.cFileName, "..")) {
continue;
}
resize();
list[list_len++] = listdir_strdup(fd.cFileName);
list[list_len] = NULL;
} while (FindNextFileA(h, &fd));
FindClose(h);
#else
DIR *dir = opendir(dir_path);
if (!dir) {
listdir_free_list(list);
return NULL;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (!strcmp(entry->d_name, ".") ||
!strcmp(entry->d_name, "..")) {
continue;
}
resize();
list[list_len++] = listdir_strdup(entry->d_name);
list[list_len] = NULL;
}
closedir(dir);
#endif
return list;
}
int
main(int argc, char *argv[]) {
if (argc < 2) {
return 1;
}
char **list = listdir(argv[1]);
if (!list) {
return 1;
}
for (char **p = list; *p; p++) {
printf("[%s]\n", *p);
}
listdir_free_list(list);
assert(listdir("...") == NULL);
assert(listdir("???") == NULL);
return 0;
}