C语言C++,dirent自创ddir结构体,实现更便捷的文件夹操作
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结构体,实现更便捷的文件夹操作相关推荐
- 简单介绍C语言使用四种方法初始化结构体
这篇文章说明了什么是结构体,介绍了结构体的概念和使用优点,在C语言中如何使用和初始化结构体方法,通过详细的代码展开进行说明,希望该篇文章对你有所帮助 什么是结构体 在实际问题中,一组数据往往有很多种不 ...
- c语言 输入职工工资资料,通过结构体的数组来进行操作 报告,c语言课程设计报告-职工工资管理系统...
<c语言课程设计报告-职工工资管理系统>由会员分享,可在线阅读,更多相关<c语言课程设计报告-职工工资管理系统(33页珍藏版)>请在人人文库网上搜索. 1.c 语言课程设计报告 ...
- Go语言入门(一)之 结构体
Go语言入门(一)之 结构体 类型别名 & 自定义类型 结构体 类型别名 & 自定义类型 自定义类型 type MyInt int //将MyInt定义为int类型 通过type关键字 ...
- c语言d打开文件夹,BAT批处理之文件与文件夹操作代码(附xcopy命令详解)
批处理中的文件.文件夹操作,xcopy命令的用法. 一,建bat文件自动执行复制,删除命令. 例1:复制cd.dll文件至windows\system32的bat文件内容: copy cd.dll % ...
- ACMNO.42 C语言-第几天 定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。利用结构体的在最下面
题目描述 定义一个结构体变量(包括年.月.日).计算该日在本年中是第几天,注意闰年问题. 输入 年月日 输出 当年第几天 样例输入 2000 12 31 样例输出 366 来源/分类 C语言 题目截图 ...
- c语言结构内部定义指针,C语言知识补漏(一)结构体指针以及位域定义
一.结构体指针 typedef struct { unsigned long int DATA; unsigned long int DIRECTION; unsigned long int INTE ...
- C语言及程序设计进阶例程-12 结构体成员的引用
贺老师教学链接 C语言及程序设计进阶 本课讲解 结构体作函数参数 #include <stdio.h> struct Student {int num;char name[20];cha ...
- c语言如何宏定义枚举型结构体,C语言学习笔记--枚举结构体
枚举 枚举是一种用户定义的数据类型,它用关键字enum以如下语法格式来声明: enum 枚举类型名字 {名字0,名字1,...,名字n}: 枚举类型名字通常并不真的使用,要用的是大括号里面的名字,因为 ...
- C语言:关键字---struct(声明结构体类型)
C语言32个关键字 有32个关键字详细说明,还有跳转链接! 一.struct-简介 struct就是结构体,用来描述需要相同类型或不同类型数据的数据对象. 通俗的说法就是打包封装,将一些分散的数据整合 ...
- c语言中结构体变量怎么初始化为0,C语言高级编程:数组和结构体初始化为0的方法...
测试平台:64位 X86 Ubuntu 1. 代码: #include #include struct st_stu { char *name; int age; int class; }; void ...
最新文章
- 怎么知道一名研究生有没有科研潜力?
- Windows Server2003 sp2重装IIS后无法浏览asp.net网页解决方法
- Springsecurity之AccessDecisionManager
- ESP32 官方文档(三)分区表
- java多字段排序,Java8对多个字段排序
- 2021年Java开发者应该学习的技术
- CodeForces 877E DFS序+线段树
- eclipse插件下载地址
- 物流系统管理课程(九)
- Matlab 口罩识别
- IOS越狱插件安装后设置里边未显示
- 天线发射功率计算公式_天线增益的定义/计算公式/发射功率
- 遭遇灰鸽子BackDoor.Gpigeon.ymg新变种
- 2022骨传导蓝牙耳机哪个最专业、目前最好的骨传导耳机
- 64位 iee754_IEEE754浮点数2008版
- 实例讲解:JAVA SOAP技术(2)完
- 51单片机+LCD12864的万年历Proteus仿真
- unity碰撞检测函数,碰撞信息获取,触发检测,使用粒子系统创建火焰,创建动画(火光闪烁),导航系统,通过导航系统控制人物移动,控制摄像机的跟随,控制角色动画播放
- 用java实现圆柱体体积
- kali metasploit 制作后门程序远程操控基本使用方法
热门文章
- DevOps落地实践:通讯行业系列:NTT COMWARE之Devaas
- 计算机界面右下角,电脑开机卡主板界面右下角显示B4~
- 项目进度管理(下)(重要考点)
- [填坑]ubuntu16.04安装腾达U12无线网卡驱动
- erphpdown9.64插件加Modown1.9模板主题下载
- jsZip上传,jsZip压缩文件并上传到服务器
- HDFS教程(06)- HDFS纠删码
- 中望cad自定义快捷键命令_中望cad常用快捷键及命令
- 操作系统——内存映射文件
- 用计算机绘制机械图样,机械制图教程—1-5绘图方法和步骤