Linux C/C++ 利用scandir和alphasort遍历目录文件并排序

您所在的位置:网站首页 毕业论文写给老师的话 Linux C/C++ 利用scandir和alphasort遍历目录文件并排序

Linux C/C++ 利用scandir和alphasort遍历目录文件并排序

2023-06-04 11:04| 来源: 网络整理| 查看: 265

目录scandir,alphasort,versionsort函数原型alphasort和versionsort示例

之前讲述了如何利用readdir/readdir_r,对指定目录进行遍历并输出,参见:Linux C 讲解系统调用readdir, readdir_r 以及如何遍历目录下的所有文件

这里讲述利用scandir和alphasort如何遍历指定目录,并对文件名排序输出。

scandir,alphasort,versionsort

scandir,alphasort,versionsort 可搭配用于扫描指定目录dirp(不含子目录)下,满足filter过滤模式的文件,返回的结果通过qsort排序存放到namelist数组中(由scandir函数调用malloc分配空间),比较子用的是compar。

函数原型

查看man scandir(3)

#include int scandir(const char *dirp, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)); int alphasort(const void *a, const void *b); int versionsort(const void *a, const void *b); alphasort和versionsort

alphasort和versionsort 作为比较函数,原型相同,可传递给compar。其区别是, 1)遵循的标准不一样 scandir,alphasort和遵循POSIX.1-2008; versionsort是GNU扩展; 也就是说,两者需要的宏定义不一样:alphasort需要_BSD_SOURCE || _SVID_SOURCE支持,versionsort需要_GNU_SOURCE支持。

2)实现时,调用的比较函数不一样 alphasort调用的是strcoll,versionsort调用的是strverscmp。

对于strcoll: 比较是基于字符串被解释为,适合当前语言环境的LC_COLLATE类别,也就是说大多数情况下,字符串是ASCII编码。

对于strverscmp: strcmp会将文件jan1, jan2, ..., jan9, jan10,排成字典序jan1, jan10, ..., jan2, ..., jan9。而strverscmp将里面的数字做了修正,会得到jan1, jan2, ..., jan9, jan10这样的排序。 其比较的字符串并非LC_COLLATE

LC_COLLATE的描述参见man setlocale(3)

LC_COLLATE for regular expression matching (it determines the meaning of range expressions and equivalence classes) and string collation.

翻译一下:

对于正则表达式匹配 (它决定了范围表达式和等价类的含义)和字符串校勘。

从这里看不出什么,可参见这篇文章setlocale()函数详解——C语言,可知,用setlocale设置LC_COLLATE会影响strcoll和strxfrm,其C字符串是ASCII编码。

示例

用scandir和alphasort,scandir和versionsort 分别顺序、逆序打印指定目录下的文件名。 注意:打印文件的顺序,跟使用的比较函数无关,而是取决于变量存放结果的namelist的访问顺序。

#include #include /* 顺序打印指定目录下文件 */ void test_scandir1() { struct dirent **namelist; int n; n = scandir(".", &namelist, NULL, alphasort); if (n < 0) perror("scandir error"); else { for (int m = 0; m < n; ++m) { printf("%s\n", namelist[m]->d_name); free(namelist[m]); } free(namelist); } } /* 逆序打印指定目录下文件 */ void test_scandir2() { struct dirent **namelist; int n; n = scandir(".", &namelist, NULL, versionsort); if (n < 0) perror("scandir error"); else { while (n--) { printf("%s\n", namelist[n]->d_name); free(namelist[n]); } free(namelist); } }

本文来自博客园,作者:明明1109,转载请注明原文链接:https://www.cnblogs.com/fortunely/p/15869825.html



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3