スポンサーリンク

Unix系OS(FreeBSDやLinuxなど)は、ディレクトリ情報(ディレクトリエントリ)
を取得するには、opendir()/readdir()/closedir()を使えば取得することが
できます。

より簡単にディレクトリエントリのリストを取得する方法があります。
それは、scandir()関数を利用することです。

scandir()関数は、指定されたディレクトリを走査し、
ディレクトリのエントリのリストを作成します。
エントリの情報は、malloc()によってメモリを確保されるため、
不要になったときにfree()関数でメモリを開放する必要があります。

scandirの定義
#include <sys/types.h>
#include <dirent.h>

int
scandir(const char *dirname, struct dirent ***namelist,
	int (*select)(struct dirent *),
	int (*compar)(const void *, const void *));


scandir.c

カレントディレクトリのディレクトリエントリのリストを取得し、
表示するサンプルプログラムです。
scandirは成功した場合、取得したエントリの数を返します。
scandirは失敗した場合は、-1を返します。
失敗するときは、メモリが足りず、malloc()が失敗したのが原因
でしょう。

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <sys/types.h>
#include <dirent.h>

int
main (int argc, char *argv[])
{
	int	i;

	const char *dirname = ".";
	struct dirent **namelist;
	int r = scandir(dirname, &namelist, NULL, NULL);
	if(r == -1) {
		err(EXIT_FAILURE, "%s", dirname);
	}
	(void) printf ("%d\n", r);
	for (i = 0; i < r; ++i) {
		(void) printf ("%s\n", namelist[i]->d_name);
		free(namelist[i]);
	}
	free(namelist);

	exit (EXIT_SUCCESS);
}

コンパイル方法

cc scandir.c


実行結果

4
.
..
scandir.c
a.out

上記の例(scandir.c)では、第4引数の比較関数を指定していないため、
取得したリストがソート(sort)されていません。
アルファベット順にソートするには、そのための比較関数をscandirに
渡してやる必要があります。
strcmp()で比較した結果でソートすれば、アルファベット順にソート
することが可能です。

scandir_compare.c

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>

int
compar(const struct dirent **s1, const struct dirent **s2)
{
	return strcmp( (*s1)->d_name, (*s2)->d_name);
}

int
main (int argc, char *argv[])
{
	int	i;

	const char *dirname = ".";
	struct dirent **namelist;
	int r = scandir(dirname, &namelist, NULL, compar);
	if(r == -1) {
		err(EXIT_FAILURE, "%s", dirname);
	}
	(void) printf ("%d\n", r);
	for (i = 0; i < r; ++i) {
		(void) printf("%s\n", namelist[i]->d_name);
		free(namelist[i]);
	}
	free(namelist);

	exit (EXIT_SUCCESS);
}

また、アルファベット順にソートする場合は、自分でオリジナルの
ソート関数を作らなくても、alphasort()関数をscandir()に渡して
やれば、簡単にできます。
scandir_alphasort.c

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>

int
main (int argc, char *argv[])
{
	int	i;

	const char *dirname = ".";
	struct dirent **namelist;
	int r = scandir(dirname, &namelist, NULL, alphasort);
	if(r == -1) {
		err(EXIT_FAILURE, "%s", dirname);
	}
	(void) printf ("%d\n", r);
	for (i = 0; i < r; ++i) {
		(void) printf("%s\n", namelist[i]->d_name);
		free(namelist[i]);
	}
	free(namelist);

	exit (EXIT_SUCCESS);
}

scandir_select.c

scandir()の第3引数には、ディレクトリエントリをリストに含めるか
どうかを決めるための関数を指定することができます。
たとえば、 '.'(ドット)で始まる名前は、リストに含めない例を
示します。

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>

int
selects(struct dirent *dir)
{
	if(dir->d_name[0] == '.')
	{
		return (0);
	}
	return (1);
}

int
main (int argc, char *argv[])
{
	int	i;

	const char *dirname = ".";
	struct dirent **namelist;
	int r = scandir(dirname, &namelist, selects, alphasort);
	if(r == -1) {
		err(EXIT_FAILURE, "%s", dirname);
	}
	(void) printf ("%d\n", r);
	for (i = 0; i < r; ++i) {
		(void) printf("%s\n", namelist[i]->d_name);
		free(namelist[i]);
	}
	free(namelist);

	exit (EXIT_SUCCESS);
}

実行結果

.や...が含まれなくなりました。
2
a.out
scandir.c

スポンサーリンク
スポンサーリンク
 
いつもシェア、ありがとうございます!


もっと情報を探しませんか?

関連記事

最近の記事

人気のページ

はてなの人気のブックマーク

スポンサーリンク
 

過去ログ

2019 : 01 02 03 04 05 06 07 08 09 10 11 12
2018 : 01 02 03 04 05 06 07 08 09 10 11 12
2017 : 01 02 03 04 05 06 07 08 09 10 11 12
2016 : 01 02 03 04 05 06 07 08 09 10 11 12
2015 : 01 02 03 04 05 06 07 08 09 10 11 12
2014 : 01 02 03 04 05 06 07 08 09 10 11 12
2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12

サイト

Vim入門

C言語入門

C++入門

JavaScript/Node.js入門

Python入門

FreeBSD入門

Ubuntu入門

セキュリティ入門

パソコン自作入門

ブログ

トップ


プライバシーポリシー