三种方式列出目录下所有文件


#include <curses.h>

int main() {
	initscr();
	getch();
	endwin();
	return 0;
}
这个是Linux 下getch的用法, 注意的情况,当然只有两个了。
1. getch()用之前, 需要加上inistscr(), endwin(), 才能出现一个空界面,让你随便输入一个字符,再返回到命令行模式。

2. 编译时, 由于 curses.h对应的库函数非标准的官方函数库,需要在编译的时候,把这个函数库链接进来。

gcc test.c -o test -l curses

三种方式 实现列某个目录下面所有文件的目的。

1. 用指针, 传递指针

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

int LEN = 0;
int output(char *arr[]);
char *arr[1000];

int markName(char *name, char *arr[]) {
	struct dirent *dp = NULL;
	struct stat buf;
	DIR *dir;
//	char **pArr = &arr[0];
//	int i;

	if (lstat(name, &buf) != 0) {
		printf("lstat error!, name = %s\n", name);
	}
	if (S_ISREG(buf.st_mode)) {
		char *p = (char *) malloc(sizeof(char) * (strlen(name) + 1));
		memset(p, '\0', sizeof(char) * (strlen(name) + 1));
		strncpy(p, name, strlen(name));
		arr[LEN++] = p;

//		for (i = 0; i < LEN; i++) {
//			printf("arr[%d] = %s \n", i, arr[i]);
//		}
//
//		printf("------------------LEN-1 = %d-------------------\n", LEN - 1);

	} else if (S_ISDIR(buf.st_mode)) {

		dir = opendir(name);

		while ((dp = readdir(dir)) != NULL ) {
			if (strncmp(dp->d_name, ".", 1) == 0)
				continue;

			char newName[100] = { '\0' };
			//			bzero(newName, '\0');
			strcpy(newName, name);
			strcat(newName, "/");
			strcat(newName, dp->d_name);
			printf("In S_ISDIR and LEN = %d\n", LEN);
			markName(newName, arr);
			/*
			 * 这道题中,传递的参数是arr, 而不是arr+LEN, 因为每次我们赋值的时候, 都是赋的arr[LEN++] = p;
			 * 由于惯性思维, 一直传成了arr+LEN了, 整了好久才想到是这个问题。
			 * printf("In S_ISDIR and LEN = %d\n", LEN);的值,竟然出现了9次。是由于while((dp = readdir(dir))每次读到一个文件都会进行一次markName
			 * 而如果是碰到文件夹的话,就会多出现一次。
			 */
		}
		closedir(dir);
	}
	return 0;
}

int main() {

//	int i = 0;
//	for (i = 0; i < 1000; i++) {
//		arr[i] = (char *) malloc(sizeof(char *));
//		memset(arr[i], '\0', sizeof(char *));
//	}
//
//	char *tArr[1000];
//	for (i = 0; i < 1000; i++) {
//		tArr[i] = (char *) malloc(sizeof(char *));
//		memset(tArr[i], '\0', sizeof(char *));
//	}
//	for (i = 0; i < 1000; i++) {
//		free((void *) tArr[0]);
//	}

	markName("/etc/yum.repos.d", arr);

	output(arr);

	return 0;
}

int output(char *arr[]) {
	int i;

	printf("%d\n", sizeof("abc")); // 返回4
	printf("%d\n", strlen("abc")); // 返回3
	printf("%d\n", sizeof(arr) * 1000); // 返回4000, 因为arr会被当成一个指针来看
	for (i = 0; i < LEN; i++) {
		printf("LEN = %d, %s\n", i, arr[i]);
	}
	for (i = 0; i < LEN; i++) {
		free((void *) arr[i]);
	}

	return 0;
}

Note: 
1. sizeof("abc") 返回值4, 而strlen("abc")返回值是3,sizeof(arr)(arr为指针数组), 结果仍回为,因为arr是一个指针,只是指向了指针数组而已。
2.  参数的传递,最先写成了arr +LEN,血的教训呀,整了那么久,因为我们在用的时候,用的是arr[LEN++], 所以,传arr就行了。

3. 在S_ISDIR中, 执行了9次,是因为在while 语句中执行了9次,而每执行一次while,就会有一个markName,最先整成是进了目录9次了。

第二种方法,用指针数组, 不传递指针数组

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <malloc.h>

static int LEN = 0;
int output(char *arr[]);
char *arr[1000];

int markName(char *name) {
	struct dirent *dp = NULL;
	struct stat buf;
	DIR *dir;

	if (lstat(name, &buf) != 0) {
		printf("lstat error!, name = %s\n", name);
	}
	if (S_ISREG(buf.st_mode)) {
		/*
		 * 为何 dp->d_name的值报错,那是因为,如果是普通文件的话, 这个值, 根本就不存在,只有目录的时候, 才能用 dp->d_name
		 * 为何用 arr[LEN++] 输出的值是莫名其妙的, 那是因为, arr[LEN++]指针,指向了一个局部变量,而局部变量在函数退出后,就消失了
		 * 所以值是莫名其妙的,
		 * 如果是Segementation fault错误, 则应该看一下定义的变量,是否已经初始化了。指针是否指到了局部变量去了。
		 * 如果提示隐式声明与内建函数‘malloc’不兼容, 则应该是malloc函数的 头文件 没有被 包含
		 * 如果运行的时候, 说是undefined reference to strscr这样的错误, 就要看一下, 是不是函数 中用到了非标准 库里面的函数,
		 * 运行的时候, 需要加上 l curses来说明 。
		 */
		char *p = (char *) malloc(sizeof(char) * (strlen(name) + 1));
		memset(p, '\0', sizeof(char) * (strlen(name) + 1));
		strncpy(p, name, strlen(name));
		arr[LEN++] = p;
//		printf("dp -> d_name = %s, LEN -1 = %d, arr[LEN-1] = %s \n", name,
//				LEN - 1, arr[LEN - 1]);
	} else if (S_ISDIR(buf.st_mode)) {

		dir = opendir(name);

		while ((dp = readdir(dir)) != NULL ) {
			if (strncmp(dp->d_name, ".", 1) == 0)
				continue;

			char newName[100] = { '\0' };
			//			bzero(newName, '\0');
			strcpy(newName, name);
			strcat(newName, "/");
			strcat(newName, dp->d_name);

			markName(newName);
		}
		closedir(dir);
	} else {
		arr[LEN++] = name;
	}
	return 0;
}

int main() {


	markName("/etc/yum.repos.d");

	output(arr);

	return 0;
}

int output(char *arr[]) {
	int i;
	for (i = 0; i < LEN; i++) {
		printf("LEN = %d, %s\n", i, arr[i]);
	}
	return 0;
}
Note: 

1. 为何 dp->d_name的值报错,那是因为,如果是普通文件的话, 这个值, 根本就不存在,只有目录的时候, 才能用 dp->d_name
2. 为何用 arr[LEN++] 输出的值是莫名其妙的, 那是因为, arr[LEN++]指针,指向了一个局部变量,而局部变量在函数退出后,就消失了, 所以值是莫名其妙的。需要用malloc去开辟一部分空间, 然后存起来, 回到主函数中间,才能打印得出来。

3. 如果是Segementation fault错误, 则应该看一下定义的变量,是否已经初始化了。指针是否指到了局部变量去了。

4. 如果提示隐式声明与内建函数‘malloc’不兼容, 则应该是malloc函数的 头文件 没有被 包含。

5. 如果运行的时候, 说是undefined reference to strscr这样的错误, 就要看一下, 是不是函数 中用到了非标准 库里面的函数,运行的时候, 需要加上 l curses来说明 。

第三种方式, 用数组来实现。

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

int LEN = 0;
char arr[100000][100] = { { '\0' } };

int markName(char *);

int main() {
	int i;
	markName("/dev\0");

	for (i = 0; i < LEN; i++) {
		printf("LEN = %d, %s\n", i, arr[i]);
	}

	return 0;
}

int markName(char *name) {
	struct dirent *dp;
	struct stat buf;
	DIR *dir;

	if (lstat(name, &buf) != 0) {
		printf("lstat error!, name = %s\n", name);
	}

	if (S_ISDIR(buf.st_mode)) {

		dir = opendir(name);

		while ((dp = readdir(dir)) != NULL ) {
			if (strncmp(dp->d_name, ".", 1) == 0)
				continue;

			char newName[100] = { '\0' };
//			bzero(newName, '\0');
			strcpy(newName, name);
			strcat(newName, "/");
			strcat(newName, dp->d_name);

			markName(newName);
		}
		closedir(dir);

	} else if (S_ISREG(buf.st_mode)) {
		strcpy(arr[LEN++], name);
	} else if (S_ISLNK(buf.st_mode)) {
		strcpy(arr[LEN++], name);
	} else {
		strcpy(arr[LEN++], name);
	}
	return 0;
}

Note:

1. 数组的初始化 char *name = {'\0'}, 自动把后面的, 也设成'\0'

2. bzero(name,'\0') , 应该包含头文件 #include <strings.h>

3. markName的时候,不要去传递形参,他可能随时会消失。

4. strcpy(arr[LEN], name),  前面这个参数,应该要分配空间的。现在建议用strncpy(arr[LEN], name, strlen(name)+1), 长度加1, 把'\0'也复制过来。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值