c语言scandir函数排序,关于C ++:如何在scandir中参数化选择函数

scandir()函数扫描目录dir,调用

每个目录项上的select()为" int(* filter)(const struct dirent *)"

如何将模式值作为参数传递给过滤器中使用的fnmatch(const char * pattern,const char * string,int flags)函数?

这是我的示例代码

int my_selectgrf(const struct dirent *namelist)

{

int  r = 0;

char     my_pattern[] ="*.grf";

r = fnmatch(my_pattern, namelist->d_name, FNM_PERIOD);

return (r==0)?1:0;

}

scandir("/pub/data/grf", &namelist, my_selectgrf, alphasort);

我的目标是能够使用my_pattern作为输入参数。

当您执行代码中显示的操作时会发生什么? 您会收到编译错误吗? 运行时错误? 它不能按预期工作(在这种情况下,实际和预期结果是什么?)

my_pattern还是pattern?

my_pattern,对不起,我已经更正了代码

简短的答案:您不能。这是一个糟糕透顶的API,完全可耻的是,直到2008年才在POSIX中添加了类似的东西(基于glibc中的错误设计)。这类API尚无法在20年前取消参数化或将其传递给上下文的方式。

话虽如此,有一些解决方法:

方法1:使用全局变量,并且如果您的代码需要是线程安全的,请通过锁定确保一次只有一个线程可以将scandir与给定的扫描功能一起使用。当然,这会序列化使用情况,如果您实际上想从多个线程中调用该函数,则可能不可接受。

方法2:使用线程本地存储,或者使用GCC __thread关键字(或者G11仍然不接受C11 _Thread_local关键字)或POSIX pthread_setspecific及其家族。这是相当干净的,但是不幸的是,它可能是不正确的。如果scandir的实现内部使用了多个线程,则该参数可能无法在某些调用scan函数的调用中使用。目前,我不相信scandir的多线程实现。

现在,更好的解决方案:

放弃scandir并编写您自己的函数,以使用正确的API进行相同的操作。反正只有几行。

正是我在写...为您+1。 另外,如果涉及到Unix信号,尤其是老式信号API,可能还会有重入问题。 太糟糕了!

@R ..感谢您的建议,在哪里可以找到scandir的源代码?

scandir的glibc源在这里:[code.metager.de/source/xref/gnu/glibc/dirent/scandirat.c]。 请注意,对于可移植代码(即非glibc目标),应将readdir()调用替换为readdir_r()(并采取所有谨慎的readdir_r()预防措施)。

实际上不推荐使用readdir_r,因为它在没有NAME_MAX的系统上不安全。 使用readdir。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值