C语言,C++的文件夹操作常见的只有opendir(),readdir(),closedir(),rewinddir(),在<dirent.h>中有DIR,struct dirent两个结构体,对系统fcntl进行复杂操作,最后就给出个d_name名字能看懂(linux还有d_type)

每次使用dirent时常常需要把路径拼接起来,跳过最前面的两个“文件夹”:.(本身)和..(上级文件夹),windows还需要stat判断文件类型。

这样复杂的处理代码,用一次dirent就得写一次,还很冗余,散架易错。我们需要一套半自动处理结构,简化代码,减轻应用层负担。于是我个人写了ddir包装体,实现一键拼路径、调点点、判断类型。

struct _ddir {

char* _path; 含完整路径结果

int _catPos; strcpy位置

short _flag;

short d_type; windows还能算type

char* d_name; 与struct dirent同名兼容,放心替换

DIR* _dir;

};

typedef struct _ddir ddir;

常见的dirent使用方法如下:

void func(void)(整体标记)

{ const char* pathdir="/storage/emulated/0/";(斜杠结尾)

char pathbuf[256];

strcpy(pathbuf,pathdir);

strcat(pathbuf,ent->d_name);

然后pathbuf才是完整路径,才能用。

对于Windows,struct dirent中没有d_type,难以区分文件还是文件夹,就要stat(),毕竟dirent全称是directory entry(文件夹入口)。

struct stat st;

if(stat(pathbuf,&st)==0)

{ if(S_ISDIR(st.st_mode)) type=4 //文件夹

if(S_ISREG(st.st_mode)) type=8 //文件

} ...

}

我的ddir半自动工作原理:

void* myreaddir(x)

{ retptr=readdir(x);

func();

return retptr;

}

这就叫包装,使得将来的功能使用更简洁,这就值得。自己动手,丰衣足食。于是我把自创源码免费分享给大家,用就拿走。欢迎讨论意见,给变量取个更好听的名字。

如果对您有帮助,点个赞可以让更多人看到~

#ifndef _DDIR_H //Writer: Dexam
#define _DDIR_H //Date: 2022.4.23
#include <dirent.h>
#include <stdlib.h> //malloc()
#include <string.h> //strcpy(),strlen()
#include <errno.h> //path length < DDIR_PATHSIZE
//windows: #include <stat.h> type 4,8

struct _ddir {
  char* _path;
  int _catPos;
  short _flag;
  short d_type;
  char* d_name;
  DIR* _dir;
};
typedef struct _ddir ddir;

#define DDIR_PATHSIZE 256

#define _DDIR_ONDIR 0x01
#define _DDIR_SET 0x02
#define _DDIR_EOF 0x04

#define deod(f) (_Bool)((f)->_flag&_DDIR_EOF)

ddir* ddiropen(const char*);
ddir* ddirwrap(DIR*,const char*);
int ddirclose(ddir*);
ddir* ddirread(ddir*);
//use as readdir() p->d_name, p->d_type

int ddirget(ddir*);
//return item type, ".",".." skipped
/* errno for path overflow:
14: Bad address
36: File name too long
*/

#if 1 //Linux:
#define DIR_SLASH '/'
int ddirtype(ddir* dp,struct dirent* ent)
{    return ent->d_type;}
#else //Windows:
#define DIR_SLASH '\\'
int ddirtype(ddir* dp,struct dirent* ent)
{    int x,ftype=0;
    struct stat st;
    if(stat(dp->_path,&st)??) {
        x=st.st_mode;
        if(S_ISDIR(x)) ftype=4;
        else if(S_ISREG(x)) ftype=8;
        else if(S_ISLNK(x)) ftype=10;
    }
    return ftype;
}
#endif

ddir* ddirwrap(DIR* fdir,const char* path)
{
    int catPos;
    ddir* dp=NULL;
    char* pathbuf=NULL;
    if(fdir!=NULL)
        dp=(ddir*)malloc(sizeof(ddir));
    if(dp!=NULL)
        pathbuf=(char*)malloc(DDIR_PATHSIZE);
    if(pathbuf==NULL) {
        free(dp);
        return NULL;
    }
    if(path!=NULL) {
        if(path[0]==0||strlen(path)>= DDIR_PATHSIZE)
            path=NULL;
    }
    if(path!=NULL) {
        catPos=strlen(strcpy(pathbuf,path));
        if(pathbuf[catPos-1]!=DIR_SLASH) {
            pathbuf[catPos]=DIR_SLASH;
            pathbuf[catPos+1]=0;
            catPos++;
        }
    } else {
        pathbuf[0]=DIR_SLASH;
        pathbuf[1]=0;
        catPos=1;
    }
    dp->_path=pathbuf;
    dp->_catPos=catPos;
    dp->d_type=0;
    dp->d_name=NULL;
    dp->_dir=fdir;
    dp->_flag=_DDIR_ONDIR|_DDIR_SET;
    return dp;
}

ddir* ddiropen(const char* path)
{
    DIR* fdir=NULL;
    ddir* dp=NULL;
    fdir=opendir(path);
    if(fdir!=NULL) {
        dp=ddirwrap(fdir,path);
        if(dp==NULL)
            closedir(fdir);
    }
    return dp;
}

ddir* ddirread(ddir* dp)
{
    struct dirent* ent=NULL;
    if(dp==NULL)
        return NULL;
    if(dp->_flag&_DDIR_ONDIR) {
        ent=readdir(dp->_dir);
        if(ent!=NULL) {
            if(dp->_catPos + strlen(ent->d_name) >= DDIR_PATHSIZE) {
                ent=NULL;
                errno=36;
            }
        } else { //end of directory
            dp->_flag=(dp->_flag&~_DDIR_SET)|_DDIR_EOF;
        }
        if(ent!=NULL) {
            strcpy(dp->_path + dp->_catPos,ent->d_name);
            dp->d_name=ent->d_name;
            dp->d_type= ddirtype(dp,ent);
            return dp;
        } else {
            dp->d_name=NULL;
            dp->d_type=0;
            dp->_path[dp->_catPos]=0;
        }
    }
    return NULL;
}

int ddirget(ddir* dp)
{
    void* p;
    char* s;
    p=ddirread(dp);
    if(p!=NULL) {
        if(dp->_flag&_DDIR_SET) {
            s= dp->_path + dp->_catPos;
            if(s[0]=='.'&&s[1]==0)
                p=ddirread(dp);
            if(s[0]=='.'&&s[1]=='.'&&s[2]==0)
                p=ddirread(dp);
            dp->_flag &=~_DDIR_SET;
        }
    }
    if(p!=NULL)
        return dp->d_type;
    else
        return 0;
}

int ddirclose(ddir* dp)
{
    if(dp==NULL)
        return -1;
    if(dp->_path!=NULL) {
        free(dp->_path);
        dp->_path=NULL;
    }
    if((dp->_flag&_DDIR_ONDIR)&&dp->_dir!=NULL)
        closedir(dp->_dir);
    dp->_dir=NULL;
    dp->_flag=0;
    free(dp);
    return 0;
}

int test_printdir(const char* path)
{
    int i,ftype;
    ddir *dp=ddiropen(path);
    if(dp==NULL) {
        printf("failed to opendir %s\n",path);
        return 0;
    }
    ftype=ddirget(dp);
    for(i=1;!deod(dp);++i) {
        switch(ftype) {
            case 4: printf("%d.directory:  %s\n%s\n\n",
                i,dp->d_name,dp->_path);
                break;
            case 8: printf("%d. file:    %s\n%s\n\n",
                i,dp->d_name,dp->_path);
                break;
            default: printf("%d.unknown(type:%d): %s\n%s\n\n",
                i,ftype,dp->d_name,dp->_path);
        }
        ftype=ddirget(dp);
    }
    return i-1;
}
int test_copydir(const char* path)
{
    int i,ftype;
    char namebuf[256]="/storage/emulated/0/sample/";
    int destCatPos=strlen(namebuf);
    ddir *dp=ddiropen(path);
    if(dp==NULL) {
        printf("failed to opendir %s\n",path);
        return 0;
    }
    ftype=ddirget(dp);
    for(i=1;!deod(dp);++i) {
        switch(ftype) {
            case 4: strcpy(namebuf + destCatPos,dp->_path + dp->_catPos);
                printf("%d.mkdir递归: %s\n",
                i,namebuf);
                break;
            case 8: strcpy(namebuf + destCatPos,dp->_path + dp->_catPos);
                printf("%d.copy file %s\nto %s\n",
                i,dp->_path,namebuf);
                break;
            default: printf("%d.unknown(type:%d): %s\n%s\n\n",
                i,ftype,dp->d_name,dp->_path);
        }
        ftype=ddirget(dp);
    }
    return i-1;
}

#endif

//终于完了

C语言C++,dirent自创ddir结构体,实现更便捷的文件夹操作相关推荐

  1. 简单介绍C语言使用四种方法初始化结构体

    这篇文章说明了什么是结构体,介绍了结构体的概念和使用优点,在C语言中如何使用和初始化结构体方法,通过详细的代码展开进行说明,希望该篇文章对你有所帮助 什么是结构体 在实际问题中,一组数据往往有很多种不 ...

  2. c语言 输入职工工资资料,通过结构体的数组来进行操作 报告,c语言课程设计报告-职工工资管理系统...

    <c语言课程设计报告-职工工资管理系统>由会员分享,可在线阅读,更多相关<c语言课程设计报告-职工工资管理系统(33页珍藏版)>请在人人文库网上搜索. 1.c 语言课程设计报告 ...

  3. Go语言入门(一)之 结构体

    Go语言入门(一)之 结构体 类型别名 & 自定义类型 结构体 类型别名 & 自定义类型 自定义类型 type MyInt int //将MyInt定义为int类型 通过type关键字 ...

  4. c语言d打开文件夹,BAT批处理之文件与文件夹操作代码(附xcopy命令详解)

    批处理中的文件.文件夹操作,xcopy命令的用法. 一,建bat文件自动执行复制,删除命令. 例1:复制cd.dll文件至windows\system32的bat文件内容: copy cd.dll % ...

  5. ACMNO.42 C语言-第几天 定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。利用结构体的在最下面

    题目描述 定义一个结构体变量(包括年.月.日).计算该日在本年中是第几天,注意闰年问题. 输入 年月日 输出 当年第几天 样例输入 2000 12 31 样例输出 366 来源/分类 C语言 题目截图 ...

  6. c语言结构内部定义指针,C语言知识补漏(一)结构体指针以及位域定义

    一.结构体指针 typedef struct { unsigned long int DATA; unsigned long int DIRECTION; unsigned long int INTE ...

  7. C语言及程序设计进阶例程-12 结构体成员的引用

    贺老师教学链接  C语言及程序设计进阶 本课讲解 结构体作函数参数 #include <stdio.h> struct Student {int num;char name[20];cha ...

  8. c语言如何宏定义枚举型结构体,C语言学习笔记--枚举结构体

    枚举 枚举是一种用户定义的数据类型,它用关键字enum以如下语法格式来声明: enum 枚举类型名字 {名字0,名字1,...,名字n}: 枚举类型名字通常并不真的使用,要用的是大括号里面的名字,因为 ...

  9. C语言:关键字---struct(声明结构体类型)

    C语言32个关键字 有32个关键字详细说明,还有跳转链接! 一.struct-简介 struct就是结构体,用来描述需要相同类型或不同类型数据的数据对象. 通俗的说法就是打包封装,将一些分散的数据整合 ...

  10. c语言中结构体变量怎么初始化为0,C语言高级编程:数组和结构体初始化为0的方法...

    测试平台:64位 X86 Ubuntu 1. 代码: #include #include struct st_stu { char *name; int age; int class; }; void ...

最新文章

  1. 怎么知道一名研究生有没有科研潜力?
  2. Windows Server2003 sp2重装IIS后无法浏览asp.net网页解决方法
  3. Springsecurity之AccessDecisionManager
  4. ESP32 官方文档(三)分区表
  5. java多字段排序,Java8对多个字段排序
  6. 2021年Java开发者应该学习的技术
  7. CodeForces 877E DFS序+线段树
  8. eclipse插件下载地址
  9. 物流系统管理课程(九)
  10. Matlab 口罩识别
  11. IOS越狱插件安装后设置里边未显示
  12. 天线发射功率计算公式_天线增益的定义/计算公式/发射功率
  13. 遭遇灰鸽子BackDoor.Gpigeon.ymg新变种
  14. 2022骨传导蓝牙耳机哪个最专业、目前最好的骨传导耳机
  15. 64位 iee754_IEEE754浮点数2008版
  16. 实例讲解:JAVA SOAP技术(2)完
  17. 51单片机+LCD12864的万年历Proteus仿真
  18. unity碰撞检测函数,碰撞信息获取,触发检测,使用粒子系统创建火焰,创建动画(火光闪烁),导航系统,通过导航系统控制人物移动,控制摄像机的跟随,控制角色动画播放
  19. 用java实现圆柱体体积
  20. kali metasploit 制作后门程序远程操控基本使用方法

热门文章

  1. DevOps落地实践:通讯行业系列:NTT COMWARE之Devaas
  2. 计算机界面右下角,电脑开机卡主板界面右下角显示B4~
  3. 项目进度管理(下)(重要考点)
  4. [填坑]ubuntu16.04安装腾达U12无线网卡驱动
  5. erphpdown9.64插件加Modown1.9模板主题下载
  6. jsZip上传,jsZip压缩文件并上传到服务器
  7. HDFS教程(06)- HDFS纠删码
  8. 中望cad自定义快捷键命令_中望cad常用快捷键及命令
  9. 操作系统——内存映射文件
  10. 用计算机绘制机械图样,机械制图教程—1-5绘图方法和步骤