本程序来自《unix环境高级编程》第三版 图1-3
程序名:myls.c
#include "apue.h"
#include <dirent.h>
int main(int argc,char *argv[])
{
DIR *dp;
struct dirent *dirp;
if(argc!=2)
err_quit("usage:ls directory_name");
if((dp=opendir(argv[1]))==NULL)
err_sys("can't open %s",argv[1]);
while((dirp=readdir(dp))!=NULL)
printf("%s\n",dirp->d_name);
closedir(dp);
exit(0);
}
编译出现错误,如下图:
错误是由于没有“apue.h”这个文件。apue是Advanced Programming in the UNIX Environment的缩写,apue.h是作者自己定义的头文件。因此,需要从APUE的网站上下载源码,导入apue.h等编译依赖的文件。进入网站http://www.apuebook.com/ , 选择对应版本,下载并解压即可。
将apue.h复制到/usr/include/:
重新编译,又出现错误:
需要找到“err_quit”和“err_sys”声明的文件,将其导入。它们在的文件为“error.c”。
将error.c复制到/usr/include/:
打开目录/usr/include:
打开文件apue.h:
在apue.h文件末尾的#endif /* _APUE_H */前面添加代码#include "error.c",然后保存文件:
重新编译,没有报错,默认生成a.out:
现在我们测试一下这个程序:
从上图可以看出根目录下的所有文件。
DIR结构体:
struct __dirstream
{
void *__fd; /* `struct hurd_fd' pointer for descriptor. */
char *__data; /* Directory block. */
int __entry_data; /* Entry number `__data' corresponds to. */
char *__ptr; /* Current pointer into the block. */
int __entry_ptr; /* Entry number `__ptr' corresponds to. */
size_t __allocation; /* Space allocated for the block. */
size_t __size; /* Total valid data in the block. */
__libc_lock_define (, __lock) /* Mutex lock for this structure. */
};
typedef struct __dirstream DIR;
DIR结构体类似于FILE,是一个内部结构,函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用:
struct dirent *readdir(DIR *dp);
void rewinddir(DIR *dp);
int closedir(DIR *dp);
long telldir(DIR *dp);
void seekdir(DIR *dp,long loc);
由于opendir函数返回指向DIR结构的指针后,我们就将该指针传送给上面的函数等,所以并不关心DIR结构中包含了什么内容。
dirent结构体:
struct dirent
{
long d_ino; /* inode number 索引节点号 */
off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
unsigned short d_reclen; /* length of this d_name 文件名长 */
unsigned char d_type; /* the type of d_name 文件类型 */
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}
readdir函数:
头文件:#include <sys/types.h> #include <dirent.h>
定义函数:struct dirent * readdir(DIR * dir);
函数说明:readdir()返回参数dir 目录流的下个目录进入点。
返回值:成功则返回下个目录进入点. 有错误发生或读取到目录文件尾则返回NULL.