opendir、readdir和closedir函数

注意:Linux中,目录的输入格式:/mnt//fghs/mnt/fghs/mnt/fghs/mnt/fghs//是等效的,都一样。

#include <sys/types.h>

#include <dirent.h>

DIR *opendir(const char *name);

DIR *fdopendir(int fd);

返回值:出错返回NULL,并可以通过perror函数查看详细错误信息;成功,则返回一个DIR *类型的指针,该指针指向一个DIR类型的结构体,该结构体描述了所打开的目录的一些信息。可以类比open函数:FILE * fp=open( );打开一个文件,则返回一个FILE *类型的指针:包含了文件描述符、文件读写指针和I/O缓冲区三部分。则打开一个目录,返回一个DIR *类型的指针(目录指针),利用该指针可以对打开的目录进行读操作和关闭该目录

 

#include <dirent.h>

struct dirent *readdir(DIR *dirp);

作用:读一个打开了的目录,该函数可以自动遍历目录内部所有的文件,一个个自动进行遍历,直到全部遍历完。

返回值:成功,则返回一个struct dirent *类型的指针,指向struct dirent *结构体,该结构体包含了该目录中某一个文件的详细信息,包括:

struct dirent

{

    ino_t   d_ino;  // 此目录进入点(该文件)的inode

    ff_t    d_off;  // 目录文件开头至此目录进入点的位移(目录内文件为1,目录内的目录内部文件为2等等)

    signed short int   d_reclen;   // d_name 的长度, 不包含NULL字符(0、\0)

    unsigned char    d_type;      // d_name 所指的文件类型

    har   d_name[256];           // 文件名(字符串类型)

};     //后两个成员常用,记住!!

对于d_type的说明(宏定义):DT_BLK 块设备文件   DT_CHR 字符设备  DT_DIR 目录文件  DT_LNK 软链接文件  DT_FIFO管道文件   DT_REG  普通文件    DT_SOCK  套接字文件     DT_UNKNOW  未知    -D_BSD_SOURCE 编译时添加宏定义

则遍历到哪一个文件,则就返回该文件对应的struct dirent结构体。遍历完目录内部的最后一个文件后,会返回NULL,因此判断一个目录是否遍历完,判断其返回值是否为NULL即可,此时不代表出错,因此不会改变errno的值。若函数出错,也会返回NULL,且会修改errno的值。

 

#include <sys/types.h>

#include <dirent.h>

int closedir(DIR *dirp);

作用:关闭目录文件  注意,打开目录后,不要忘记关闭。

返回值:0 成功  -1失败

 

//递归读一个目录,统计一个目录内部所有普通文件的个数(注意是递归,包括子目录)。

[root@localhost dir_op]# vim read_file_num.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int countFileNum( const char * );  //函数声明int countFileNum( const char *dirName ) //定义一个统计普通文件数目的函数
{DIR *dir=NULL;dir = opendir(dirName);  //打开需要统计的目录if( dir == NULL ){perror("opendir");exit(1);}struct dirent *fx = NULL;fx = readdir( dir );   //读该目录,注意是每读一次,就自动遍历到下一个文件,因此必须要读一次,才能遍历到下一个文件。if( fx == NULL ){perror("readdir");exit(1);}int total=0;char buff[1024]={0};  //建立缓冲区while( fx )   //fx为NULL,则循环结束{if( strcmp(fx->d_name , ".") == 0 || strcmp( fx->d_name , "..") == 0 ){fx = readdir( dir );  //必须读一次,否则陷入死循环continue;}                  //字符串比较函数,排除.和..(当前目录和上级目录)if( fx->d_type == DT_DIR )  //如果是目录文件,则递归调用,注意递归思想{sprintf( buff,"%s/%s",dirName,fx->d_name );  //d_name只是目录本身的名字,不包含路劲(上级目录等)total += countFileNum( buff );}if( fx->d_type == DT_REG )total++;fx = readdir( dir );   //必须要读一次,否则不会遍历下一个文件}int qw = 0;qw = closedir(dir);if( qw==-1 ){perror("closedir");exit(1);}       //关闭目录return total;
}int main( int argc , char *argv[ ] )
{if( argc < 2 ){printf( "./a.out dirName\n");exit(1);}int num = 0;num = countFileNum( argv[1] );printf( " the number of reg file is %d.\n",num);return 0;
}

[root@localhost dir_op]# gcc -pipe -Wall -pedantic -ggdb3 read_file_num.c -o read_file_num

[root@localhost dir_op]# ls

a.out  chdir  chdir.c  fileNum  fileNum.c  haha.c  hehe.c  mkdir.c  mytest  opendir.c  readdir.c  read_file_num  read_file_num.c

[root@localhost dir_op]# ./read_file_num .

 the number of reg file is 13.   //成功统计出当前目录中的普通文件数为13.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/385385.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

146. LRU缓存机制

运用你所掌握的数据结构&#xff0c;设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作&#xff1a; 获取数据 get 和 写入数据 put 。 获取数据 get(key) - 如果密钥 (key) 存在于缓存中&#xff0c;则获取密钥的值&#xff08;总是正数&#xff09;&#xff…

dup和dup2函数

#include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd); 作用&#xff1a;dup函数实现对一个文件的文件描述符进行复制&#xff0c;复制之后该进程就会新增加一一个文件描述符指向该文件&#xff08;即实现同一个文件对应多个文件描述符&#xff0…

fcntl函数(网络编程会用)

#include <unistd.h> #include <fcntl.h> int fcntl&#xff08;int fd, int cmd&#xff09;&#xff1b; int fcntl&#xff08;int fd, int cmd, long arg&#xff09;&#xff1b;//long 长整型 int fcntl&#xff08;int fd, int cmd, struct flock *lock…

189. 旋转数组

给定一个数组&#xff0c;将数组中的元素向右移动 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: [1,2,3,4,5,6,7] 和 k 3 输出: [5,6,7,1,2,3,4] 解释: 向右旋转 1 步: [7,1,2,3,4,5,6] 向右旋转 2 步: [6,7,1,2,3,4,5] 向右旋转 3 步: [5,6,7,1,2,3,4]示例 2: 输…

58. 最后一个单词的长度

给定一个仅包含大小写字母和空格 的字符串&#xff0c;返回其最后一个单词的长度。 如果不存在最后一个单词&#xff0c;请返回 0 。 说明&#xff1a;一个单词是指由字母组成&#xff0c;但不包含任何空格的字符串。 示例: 输入: "Hello World" 输出: 5 clas…

CPU和MMU(内存管理单元)

CPU的架构&#xff1a;要求能够理解从源程序到微指令的整个经历过程&#xff1a;存储器的层次结构&#xff08;网络资源下载到硬盘、磁盘缓存、内存、Cache、寄存器&#xff09;&#xff1b;CPU的四大部分&#xff1a;ALU、CU、中断系统和寄存器&#xff1b;程序执行的整个过程…

【C++ Primer | 09】容器适配器

一、stack s.push(): 向栈内压入一个成员&#xff1b; s.pop(): 从栈顶弹出一个成员&#xff1b; s.empty(): 如果栈为空返回true&#xff0c;否则返回false&#xff1b; s.top(): 返回栈顶&#xff0c;但不删除成员&#xff1b; s.size(): 返回栈内元素…

进程控制块PCB(进程描述符)

&#xff08;1&#xff09;PCB 每个进程在内核中都有一个进程控制块&#xff08;PCB&#xff09;来维护进程相关的信息&#xff0c;Linux内核的进程控制块是task_struct结构体。grep -r “task_struct” / 可以查找根目录下&#xff0c;包含task_struct的文件文件。或者 find…

103. 二叉树的锯齿形层次遍历

给定一个二叉树&#xff0c;返回其节点值的锯齿形层次遍历。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 例如&#xff1a; 给定二叉树 [3,9,20,null,null,15,7], 3 / \ 9 20 /…

fork、getpid、getppid函数

#include <unistd.h> pid_t fork(void); 作用&#xff1a;创建一个子进程。 到目前为止&#xff0c;我们可以直到两种创建进程的方法&#xff1a;1. 通过执行二进制文件来创建一个进程&#xff0c;如&#xff1a;./a.out /bin/ls&#xff1b;2.通过fork函数来创建一个…

107. 二叉树的层次遍历 II

给定一个二叉树&#xff0c;返回其节点值自底向上的层次遍历。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09; 例如&#xff1a; 给定二叉树 [3,9,20,null,null,15,7], 3/ \9 20/ \15 7返回其自底向上的层次遍历为&#xff…

循环创建N个子进程

以循环创建5个进程为例&#xff0c;给出如下代码&#xff0c;分析其错误&#xff1a; #include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(void) {int i;pid_t pid;printf("xxxxxxxxxxx\n");for (i 0; i < 5; i){pid fork…

【C++ Primer | 19】控制内存分配

1. 测试代码&#xff1a; #include <iostream> #include <new> #include <cstring> #include <cstdlib> using namespace std;void* operator new(size_t size) {cout << "global Override operator new" << endl;if (void* p…

getuid、geteuid、getgid和getegid函数

#include <unistd.h> #include <sys/types.h> uid_t getuid(void); uid_t geteuid(void); 作用&#xff1a;getuid返回当前进程的实际用户ID&#xff1b;geteuid返回当前用户的有效用户ID。这两个总是成功&#xff0c;不会失败。 #include <unistd.h> #…

【第15章】虚函数

一、为什么基类中的析构函数要声明为虚析构函数&#xff1f; 直接的讲&#xff0c;C中基类采用virtual虚析构函数是为了防止内存泄漏。具体地说&#xff0c;如果派生类中申请了内存空间&#xff0c;并在其析构函数中对这些内存空间进行释放。假设基类中采用的是非虚析构函数&am…

进程共享(读时共享写时复制)

父子进程之间在刚fork后。父子相同处: 全局变量、.data、.bbs、.text、栈、堆、环境变量、用户ID、宿主目录&#xff08;进程用户家目录&#xff09;、进程工作目录、信号处理方式等等&#xff0c;即0~3G的用户空间是完全一样的。父子不同处: 1.进程ID 2.fork返回值 3.父进…

【C++ Primer | 08】IO库

一、istringstream类 描述&#xff1a;从流中提取数据&#xff0c;支持 >> 操作 这里字符串可以包括多个单词&#xff0c;单词之间使用空格分开 #include <iostream> #include <sstream> using namespace std; int main() {istringstream istr(&quo…

gdb调试(如何跟踪指定进程)

使用gdb调试的时候&#xff0c;gdb只能跟踪一个进程。可以在fork函数调用之前&#xff0c;通过指令设置gdb调试工具跟踪父进程或者是跟踪子进程。默认跟踪父进程。 set follow-fork-mode child 命令设置gdb在fork之后跟踪子进程。 set follow-fork-mode parent 设置跟踪父进程…

【Leetcode | 01】Backtracking

回溯算法序号题号117. 电话号码的字母组合222. 括号生成 39. 组合总和 40. 组合总和 II 46. 全排列 47. 全排列 II 60. 第k个排列 77. 组合 78. 子集 90. 子集 II 93. 复原IP地址 131. 分割回文串 216. 组合总和 III 306. 累加数 357. 计算各个位数不同的数字个数 401. 二进…

1033. 旧键盘打字(20)

旧键盘上坏了几个键&#xff0c;于是在敲一段文字的时候&#xff0c;对应的字符就不会出现。现在给出应该输入的一段文字、以及坏掉的那些键&#xff0c;打出的结果文字会是怎样&#xff1f; 输入格式&#xff1a; 输入在2行中分别给出坏掉的那些键、以及应该输入的文字。其中对…