【Linux操作系统】Linux系统编程实现递归遍历目录,详细讲解opendir、readdir、closedir、snprintf、strcmp等函数的使用

这篇具有很好参考价值的文章主要介绍了【Linux操作系统】Linux系统编程实现递归遍历目录,详细讲解opendir、readdir、closedir、snprintf、strcmp等函数的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在Linux系统编程中,经常需要对目录进行遍历操作,以获取目录中的所有文件和子目录。递归遍历目录是一种常见的方法,可以通过使用C语言来实现。本篇博客将详细介绍如何使用C语言实现递归遍历目录的过程,并提供相应的代码示例,同时解释相关函数的使用。
【Linux操作系统】Linux系统编程实现递归遍历目录,详细讲解opendir、readdir、closedir、snprintf、strcmp等函数的使用,操作系统,linux,运维,服务器

1. 相关函数介绍

1.1 opendir()

1.1.1 函数原型、参数和返回值

opendir函数用于打开一个目录,并返回一个指向DIR类型的指针,该指针用于后续的目录操作。


原型:

DIR *opendir(const char *path);

参数:

  • path:要打开的目录的路径。

返回值:

  • 返回值:如果成功打开目录,则返回一个指向DIR类型的指针;如果失败,则返回NULL

1.1.2 函数示例

下面是一个使用opendir函数打开目录的示例:

#include <stdio.h>
#include <dirent.h>

int main() {
    const char *path = "/path/to/directory";
    DIR *dir = opendir(path);
    
    if (dir == NULL) {
        perror("opendir");
        return -1;
    }
    
    // 目录操作...
    
    closedir(dir);
    
    return 0;
}

1.1.3 代码解释

在上述示例中,我们首先定义了要打开的目录路径path,然后使用opendir函数打开目录,并将返回的指针存储在dir变量中。接着,我们可以进行一些目录操作,比如使用readdir函数读取目录中的文件。最后,我们使用closedir函数关闭目录。

如果opendir函数执行失败,它会返回NULL,并将错误信息存储在全局变量errno中。我们可以使用perror函数打印出错误信息,以便调试和排查问题

需要注意的是,在使用完DIR类型的指针后,一定要记得使用closedir函数关闭目录,以释放相关的资源。



1.2 readdir()

1.2.1 函数原型、参数、返回值和结构体定义

readdir函数用于读取目录中的文件,并返回一个指向dirent结构体的指针。


原型:

struct dirent *readdir(DIR *dir);

参数:

  • dir:一个指向已打开目录的指针。

返回值:

  • 返回值:如果成功读取到下一个文件,则返回指向dirent结构体的指针;如果到达目录末尾或发生错误,则返回NULL

dirent结构体的定义如下:

struct dirent {
    ino_t d_ino;               // 文件的inode号
    off_t d_off;               // 文件在目录中的偏移量
    unsigned short d_reclen;   // 文件名的长度
    unsigned char d_type;      // 文件的类型
    char d_name[256];          // 文件名
};

1.2.2 函数示例

下面是一个使用readdir函数读取目录中文件的示例:

#include <stdio.h>
#include <dirent.h>

int main() {
    const char *path = "/path/to/directory";
    DIR *dir = opendir(path);
    
    if (dir == NULL) {
        perror("opendir");
        return -1;
    }
    
    struct dirent *entry;
    
    while ((entry = readdir(dir)) != NULL) {
        printf("%s\n", entry->d_name);
    }
    
    closedir(dir);
    
    return 0;
}

1.2.3 代码解释

在上述示例中,我们首先使用opendir函数打开目录,并将返回的指针存储在dir变量中。然后,我们使用一个循环来读取目录中的每个文件。readdir函数会返回一个指向dirent结构体的指针,我们可以通过访问d_name成员来获取文件名,并进行相应的操作。在示例中,我们简单地使用printf函数打印出文件名。最后,我们使用closedir函数关闭目录。

需要注意的是,当readdir函数返回NULL时,表示已经读取到了目录的末尾,或者发生了错误。因此,我们可以通过判断返回值是否为NULL来确定是否继续读取目录中的文件。



1.3 closedir()

1.3.1 函数原型、参数和返回值

closedir函数用于关闭之前通过opendir函数打开的目录,并释放相关资源。


原型:

int closedir(DIR *dir);

参数:

  • dir:一个指向已打开目录的指针。

返回值:

  • 返回值:如果成功关闭目录,则返回0;如果发生错误,则返回-1。

1.3.2 函数示例

下面是一个使用closedir函数关闭目录的示例:

#include <stdio.h>
#include <dirent.h>

int main() {
    const char *path = "/path/to/directory";
    DIR *dir = opendir(path);
    
    if (dir == NULL) {
        perror("opendir");
        return -1;
    }
    
    // 目录操作...
    
    if (closedir(dir) == -1) {
        perror("closedir");
        return -1;
    }
    
    return 0;
}

1.3.3 代码解释

在上述示例中,我们首先使用opendir函数打开目录,并将返回的指针存储在dir变量中。接着,我们可以进行一些目录操作。最后,我们使用closedir函数关闭目录,并检查返回值是否为-1,以判断是否发生了错误。

需要注意的是,closedir函数会释放与目录相关的资源,因此在使用完目录后,一定要记得调用closedir函数关闭目录。



1.4 snprintf()

1.4.1 函数原型、参数和返回值

snprintf函数是一个安全的字符串格式化函数,用于将格式化的数据输出到字符串中。


原型:

int snprintf(char *str, size_t size, const char *format, ...);

参数:

  • str:指向用于存储格式化结果的字符串的指针。
  • size:存储格式化结果的字符串的大小。
  • format:格式化字符串,指定输出的格式。

返回值:

  • 返回值:成功时返回写入字符串的字符数(不包括终止符),失败时返回负值。

snprintf函数的工作方式与printf函数类似,但是它会将格式化的结果存储到指定的字符串中,而不是将其输出到标准输出。


1.4.2 函数示例

下面是一个使用snprintf函数的示例:

#include <stdio.h>

int main() {
    char buffer[100];
    int num = 42;
    const char *str = "Hello, world!";
    
    int len = snprintf(buffer, sizeof(buffer), "Number: %d, String: %s", num, str);
    
    if (len >= sizeof(buffer)) {
        printf("Buffer is too small\n");
        return -1;
    }
    
    printf("Formatted string: %s\n", buffer);
    
    return 0;
}

1.4.3 代码解释

在上述示例中,我们首先定义了一个大小为100的字符数组buffer,用于存储格式化结果。然后,我们定义了一个整数变量num和一个字符串变量str,用于传递给格式化字符串。接着,我们使用snprintf函数将格式化的结果存储到buffer中,并将其输出到标准输出。最后,我们检查返回值len是否超过了buffer的大小,以判断是否缓冲区足够大以容纳格式化的结果。

需要注意的是,snprintf函数会根据指定的格式化字符串和参数进行格式化,并将结果存储到指定的字符串中。它会确保格式化的结果不会超出指定的大小,并在必要时自动截断字符串。因此,使用snprintf函数可以避免缓冲区溢出的问题。



1.5 strcmp()

1.5.1 函数原型、参数和返回值

strcmp函数用于比较两个字符串是否相等。


原型:

int strcmp(const char *s1, const char *s2);

参数:

  • s1:要比较的第一个字符串。
  • s2:要比较的第二个字符串。

返回值:

  • 返回值:如果两个字符串相等,则返回0;如果第一个字符串小于第二个字符串,则返回一个负数;如果第一个字符串大于第二个字符串,则返回一个正数。

strcmp函数会按照字典顺序逐个比较两个字符串中的字符,直到找到不相等的字符或者遇到字符串的结束符\0。如果两个字符串相等,则返回0;如果第一个字符串在字典顺序中排在第二个字符串之前,则返回一个负数;如果第一个字符串在字典顺序中排在第二个字符串之后,则返回一个正数。


1.5.2 函数示例

下面是一个使用strcmp函数比较两个字符串的示例:

#include <stdio.h>
#include <string.h>

int main() {
    const char *s1 = "Hello";
    const char *s2 = "World";
    
    int result = strcmp(s1, s2);
    
    if (result == 0) {
        printf("The strings are equal\n");
    } else if (result < 0) {
        printf("The first string is less than the second string\n");
    } else {
        printf("The first string is greater than the second string\n");
    }
    
    return 0;
}

1.5.3 代码解释

在上述示例中,我们定义了两个字符串s1s2,然后使用strcmp函数比较它们。根据返回值的不同,我们输出相应的结果。

需要注意的是,strcmp函数比较的是字符串的内容,而不是字符串的地址。因此,即使两个字符串的地址不同,只要它们的内容相同,strcmp函数会返回0。此外,strcmp函数是区分大小写的,如果要进行大小写不敏感的比较,可以使用strcasecmp函数。



2. 递归遍历目录实现

2.1 示例代码:

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

void traverse_directory(const char *path) {
    DIR *dir;
    struct dirent *entry;
    struct stat file_stat;
    
    // 打开目录
    dir = opendir(path);
    if (dir == NULL) {
        perror("opendir");
        return;
    }
    
    // 读取目录中的每个文件
    while ((entry = readdir(dir)) != NULL) {
        // 构建文件的完整路径
        char file_path[1024];
        snprintf(file_path, sizeof(file_path), "%s/%s", path, entry->d_name);
        
        // 获取文件的信息
        if (lstat(file_path, &file_stat) < 0) {
            perror("lstat");
            continue;
        }
        
        // 判断文件类型
        if (S_ISDIR(file_stat.st_mode)) {
            // 如果是目录,则递归遍历
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
                continue;
            }
            traverse_directory(file_path);
        } else {
            // 如果是文件,则打印文件名
            printf("%s\n", file_path);
        }
    }
    
    // 关闭目录
    closedir(dir);
}

int main(int argc,char *argv[]) {
    
    traverse_directory(argv[]);
    
    return 0;
}

2.2 代码解释

上述代码中,我们定义了一个traverse_directory函数来递归遍历目录。该函数接受一个路径作为参数,首先打开目录,然后读取目录中的每个文件。对于每个文件,我们首先构建文件的完整路径,然后使用lstat函数获取文件的信息。如果文件是一个目录,则递归调用traverse_directory函数;如果文件是一个普通文件,则打印文件名。最后,我们关闭目录。

main函数中,我们指定要遍历的目录路径,并调用traverse_directory函数进行遍历。

需要注意的是,上述代码中使用了dirent.hsys/stat.h头文件来操作目录和文件,以及stdio.hstring.h头文件来进行字符串操作。此外,代码中还使用了lstat函数来获取文件的信息,而不是stat函数,这是因为lstat函数可以处理符号链接。 文章来源地址https://www.toymoban.com/news/detail-652808.html

到了这里,关于【Linux操作系统】Linux系统编程实现递归遍历目录,详细讲解opendir、readdir、closedir、snprintf、strcmp等函数的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【Linux系统编程】第九弹---权限管理操作(下)

    【Linux系统编程】第九弹---权限管理操作(下)

      ✨ 个人主页:   熬夜学编程的小林 💗 系列专栏:   【C语言详解】   【数据结构详解】 【C++详解】 【Linux系统编程】 目录 1、目录权限 2、粘滞位 总结 首先提出一个问题,删除一个文件需要什么权限呢??? 回答这个问题之前我们先通过命令来看看现象。 通过上面的

    2024年04月28日
    浏览(12)
  • 【Linux操作系统】探秘Linux奥秘:shell 编程的解密与实战

    【Linux操作系统】探秘Linux奥秘:shell 编程的解密与实战

    🌈个人主页: Sarapines Programmer 🔥 系列专栏: 《操作系统实验室》 🔖诗赋清音:柳垂轻絮拂人衣,心随风舞梦飞。 山川湖海皆可涉,勇者征途逐星辉。 目录 🪐1 初识Linux OS 🪐2 shell 编程的解密与实战 🌍1. 实验目的 🌍2. 实验准备 🌍3. 实验内容 🌍4. 实验心得 📝总结

    2024年02月03日
    浏览(13)
  • 《Linux操作系统编程》第四章 屏幕编程器vi : 了解屏幕编辑器vi的概述和基本操作命令

    《Linux操作系统编程》第四章 屏幕编程器vi : 了解屏幕编辑器vi的概述和基本操作命令

    🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬

    2024年02月11日
    浏览(11)
  • 《Linux操作系统编程》 第十章 线程与线程控制: 线程的创建、终止和取消,detach以及线程属性

    《Linux操作系统编程》 第十章 线程与线程控制: 线程的创建、终止和取消,detach以及线程属性

    🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬

    2024年02月11日
    浏览(8)
  • 《Linux操作系统编程》 第六章 Linux中的进程监控: fork函数的使用,以及父子进程间的关系,掌握exec系列函数

    《Linux操作系统编程》 第六章 Linux中的进程监控: fork函数的使用,以及父子进程间的关系,掌握exec系列函数

    🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬

    2024年02月11日
    浏览(16)
  • 《Linux操作系统编程》第九章 数据查找和筛选工具 : 了解流编辑器sed和报表生成器awk的简单使用

    《Linux操作系统编程》第九章 数据查找和筛选工具 : 了解流编辑器sed和报表生成器awk的简单使用

    🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬

    2024年02月12日
    浏览(14)
  • python GUI编程--实现计算器和图书管理系统注册和登录的可视化操作

    python GUI编程--实现计算器和图书管理系统注册和登录的可视化操作

    1.简易计算器:编写程序,实现两个数的“加减乘除”,界面如图所示  2.利用tkinter设计一个登录界面,并实现各个命令按钮的功能: 3.利用tkinter设计一个下面的界面, 该界面的功能是:当单击“insert point”按钮时,第一个文本框的内容复制一份显示在第二个文本框内,当单

    2024年02月10日
    浏览(7)
  • Linux系统操作——Nginx使用OpenSSL实现https转发

    目录 一、OpenSSL创建自签名证书 1、下载安装OpenSSL  2、创建自签名的SSL证书和私钥  3、转换成.jks文件 二、配置Nginx 1、配置方法一:http和https同时监听,自动跳转https; 2、配置方法二:http自动跳转https;  3、配置方法三:http,https同时可访问; 三、开放443端口 下载地址:

    2024年02月02日
    浏览(9)
  • 【Linux操作系统】Linux中的进程和线程的概念、区别和实现的细节

    在Linux中,进程和线程是操作系统中两个重要的执行单位。它们是对程序运行时的抽象概念,用于管理和调度计算机资源。 进程是正在运行的程序的实例。它是操作系统分配资源和调度执行的基本单位。每个进程都有自己独立的内存空间,包含代码、数据、堆栈等。进程还包

    2024年02月14日
    浏览(28)
  • 学编程应该选择什么操作系统?

    学编程应该选择什么操作系统?

    今天来聊一个老生常谈的问题,学编程时到底选择什么操作系统?Mac、Windows,还是别的什么。。 作为一个每种操作系统都用过很多年的程序员,我会结合我自己的经历来给大家一些参考和建议。 接下来先分别聊聊每种操作系统的优点和不足吧。 先说下国内用户最多的操作系

    2023年04月15日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包