您设置了buf.gl_offs = 2;,并将GLOB_DOOFFS 传递给glob(),因此您告诉它在gl_argv 指针列表的开头留下两个未使用的插槽;它按照你的要求做了,这些插槽是 NULL 指针。空槽背后的想法是,代码可能想要添加一个命令名称,并且可能需要在这些槽所在的位置添加一些参数,例如,buf.gl_pathv 可以传递给execv()。 glob() 的 POSIX 规范说“最后一个路径名之后的第一个指针应该是一个空指针”,这当然是 execv() 所要求的。
用途:
#include <glob.h>
#include <stddef.h>
#include <stdio.h>
int main(void)
{
glob_t buf;
buf.gl_offs = 2;
if (glob("*.c", GLOB_DOOFFS, NULL, &buf) != 0)
{
fprintf(stderr, "glob() failed\n");
return 0;
}
printf("%ld\n", buf.gl_pathc);
printf("%s\n", buf.gl_pathv[0]);
for (size_t i = 0; i < buf.gl_pathc + buf.gl_offs + 1; i++)
{
printf("%zu: [%s]\n", i,
(buf.gl_pathv[i] == NULL ? "<null>" : buf.gl_pathv[i]));
}
globfree(&buf);
return 0;
}
这段代码是懒惰的;它依靠printf("%s\n", buf.gl_pathv[0]); 在将空指针作为字符串传递时不会崩溃(原始代码)。这不是 C 标准所要求的。主循环显示了你应该为可靠的代码做什么——你应该在调用printf()之前映射空指针。
在我的机器上,它产生了:
28
(null)
0: [<null>]
1: [<null>]
2: [alarm47.c]
3: [book41.c]
4: [checkeuid.c]
5: [dec37.c]
6: [glob61.c]
7: [grid17.c]
8: [hms37.c]
9: [int89.c]
10: [ll11.c]
11: [log41.c]
12: [pipe17.c]
13: [pipe29.c]
14: [pipe31.c]
15: [pipe43.c]
16: [pipe73.c]
17: [pipe83.c]
18: [prtree37.c]
19: [rc61.c]
20: [rep31.c]
21: [rn83.c]
22: [rn89.c]
23: [sh31.c]
24: [sh47.c]
25: [sh67.c]
26: [sh71.c]
27: [sh79.c]
28: [sh97.c]
29: [test-strsep.c]
30: [<null>]
注意buf.gl_pathc 中的计数不包括buf.gl_offs 指定的空槽或终止空指针。我不得不检查目录中的文件名列表——碰巧有 28 个.c 文件。 (早期版本的代码没有遍历名称列表。)
JFTR:我在运行 macOS Mojave 10.14.6 的 Mac 上进行了测试。