您的位置:首页 > 运维架构 > Linux

漂亮的LinuxC注释转换器--(2.1)目录级联转换算法预备及S_ISXXX宏的定义与使用

2017-01-31 17:47 369 查看
一.序:

在上一篇中,已经实现了基本的C++注释风格到C的注释风格转换,这一篇做升级程序的算法预备工作,为其达到支持目录级联转换的要求作铺垫

二.需要的基本算法说明:

可以看到Linux C函数库手册里给出了许多文件及目录函数,读者可以参考这些资料,笔者将根据需求介绍这些函数,并且使用这些函数。

三.必要的系统函数的介绍

笔者之前阅读了目录遍历这篇博文,读者可以借鉴一下,但是笔者认为网络上的这些代码是不全的,有的甚至会诱导自己走弯路,笔者陷于鸿沟之中一两天,将目录级联转换的代码推倒重来了一次,才达到自己心目中的要求,建议各位按自己的思路来,也许写的更好。

1.getopt()

作  用:   用来分析命令行参数
头文件:    #include <unistd.h>
用  法:   int getopt(int argc, char * const argv[],
const char *optstring);
说  明:
optstring中的指定的内容的意义(例如getopt(argc, argv, "ab:c:de::");)
1.单个字符,表示选项,(如上例中的abcde各为一个选项)
2.单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。(如上例中的b:c:)
3 单个字符后跟两个冒号,表示该选项后可以跟一个参数,也可以不跟。如果跟一个参数,参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(如上例中的e::,如果没有跟参数,则optarg = NULL)


为了达到可以用参数选择要进行单文件转换/目录级联转换,我选择了getopt函数。

2.opendir()

打开目录




3.mkdir()

建立目录
#include <sys/stat.h>
int mkdir(const char *path, mode_t mode);
注意:
mode为权限,0755即为linux下目录的默认权限:drwxr-xr-x


4.readdir()

建立目录




5.closedir()

关闭目录




6.lstat()

获取文件/目录的属性
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int lstat(const char *path, struct stat *buf);


man 2 stat
可以看到stat结构体是这样定义的

struct stat {
dev_t     st_dev;     /* ID of device containing file */
ino_t     st_ino;     /* inode number */
mode_t    st_mode;    /* protection */
nlink_t   st_nlink;   /* number of hard links */
uid_t     st_uid;     /* user ID of owner */
gid_t     st_gid;     /* group ID of owner */
dev_t     st_rdev;    /* device ID (if special file) */
off_t     st_size;    /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
time_t    st_atime;   /* time of last access */
time_t    st_mtime;   /* time of last modification */
time_t    st_ctime;   /* time of last status change */
};


7.realpath()



8.宏S_ISDIR()

很多文章上说它是函数,是不对的,linux内核中
/usr/src/sys/sys/stat.h
将其定义为宏,使用这个宏之前一定要先调用lstat函数,因为它的使用是这样的:

//如果是文件文件
if(S_ISDIR(statbuf.st_mode) == 0)
{}




和它类似的还有

S_ISLNK(st_mode):是否是一个连接.
S_ISREG(st_mode):是否是一个常规文件.
S_ISDIR(st_mode):是否是一个目录
S_ISCHR(st_mode):是否是一个字符设备.
S_ISBLK(st_mode):是否是一个块设备
S_ISFIFO(st_mode):是否 是一个FIFO文件.
S_ISSOCK(st_mode):是否是一个SOCKET文件


9.文件结束判断feof()





10.其次,还可以了解其他文件和目录相关的函数。

四.目录级联转换实现思路

1.大方向:需要转换的目录–>函数–>转换后存放的目录(以下简称最终目录)

2.要求:

类似cp命令,需要转换的文件是.c/.cpp文件,要达到以下要求:

(1)所有文件在最终目录中的相对路径要保持不变

(2)所有文件的属性不变

3.函数模型

void DirConvert(char *des, char *src);          //目录的递归转换
void BeginConvert(char *des, char *src);        //进行目录递归转换
(des为最终目录,src为源目录,即要进行转换的目录)


4.函数的作用:

void DirConvert(char *des, char *src);          //目录的递归转换
{
//(1)参数检测
//(2)打开des和src目录.若src不存在,则退出程序;若des不存在,则建立
//(3)读取src中的文件,调用BeginConvert函数,进行注释转换
//(4)关闭des和src目录
}


void BeginConvert(char *des, char *src);        //进行目录递归转换
{
//(1)将src,des的路径转化成绝对路径分别存于src_path,des_path中
//(2)获取src的属性。
//(3)分情况讨论
//a.如果src是文件,判断是否是.c/.cpp文件,des_path追加这一文件,然后直接调动OneFileConvert()进行转换
//b.如果src是目录,des_path追加这一目录,然后DirpConvert(des_path,src_path)

}


五.gdb调试介绍

笔者在编写的过程中,遇到了一些问题,比如未转换/只转换了一层目录,这一切都要通过调试解决,所以必须要学会gdb的带参数调试工作

(1)自行编写Makefile文件,编译工作:
make
如果要使用gdb,需要加-g参数,可以参考:
g++ convert.cpp -o convert -g
(2)调试:
gdb convert -g
(3)调试界面已经出现,开始调试,流程是:设置参数-->显示参数-->开始调试
set args -r ./tttttt ./t1
show args
b 20
r
s


可以参考gdb带参数调试
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐