![](/img/trans.png)
[英]How to get only *.txt filenames from directory in c and write it to char ** array?
[英]How can I get only txt files from directory in c?
我想在给定目录中只获取* .txt文件的名称,如下所示:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
int main(int argc, char **argv)
{
char *dirFilename = "dir";
DIR *directory = NULL;
directory = opendir (dirFilename);
if(directory == NULL)
return -1;
struct dirent *ent;
while ((ent = readdir (directory)) != NULL)
{
if(ent->d_name.extension == "txt")
printf ("%s\n", ent->d_name);
}
if(closedir(directory) < 0)
return -1;
return 0;
}
我怎样才能在纯unixs c中做到这一点?
首先,Unix没有文件扩展的概念,因此struct dirent
上没有extension
成员。 其次,你无法将字符串与==
进行比较。 你可以使用类似的东西
bool has_txt_extension(char const *name)
{
size_t len = strlen(name);
return len > 4 && strcmp(name + len - 4, ".txt") == 0;
}
> 4
部分确保文件名.txt
不匹配。
(从<stdbool.h>
获取bool
。)
您可以使用glob()
函数调用。 更多信息使用您最喜欢的搜索引擎,Linux手册页或此处 。
#include <glob.h>
#include <stdio.h>
int main(int argc, char **argv) {
const char *pattern = "./*.txt";
glob_t pglob;
glob(pattern, GLOB_ERR, NULL, &pglob);
printf("Found %d matches\n", pglob.gl_pathc);
printf("First match: %s\n", pglob.gl_pathv[0]);
globfree(&pglob);
return 0;
}
可能性:
while ((ent = readdir (directory)) != NULL)
{
const size_t len = strlen(ent->d_name);
if (len > 4 &&
ent->d_name[len - 4] == '.' &&
ent->d_name[len - 3] == 't' &&
ent->d_name[len - 2] == 'x' &&
ent->d_name[len - 1] == 't')
{
printf ("%s\n", ent->d_name);
}
}
你几乎就在那里,你只需要检查文件名是否以.txt
结尾。 一种方法是使用strcmp
, strcasecmp
或memcmp
:
while ((ent = readdir (directory)) != NULL)
{
int len = strlen(ent->d_name);
if(len > 4 && memcmp(ent->d_name + len - 4, ".txt", 4) == 0) // only checks lowercase
{
// It's a .txt file - now check that it's a regular file
char filename[PATH_MAX];
snprintf(filename, sizeof(filename), "%s/%s", dirFilename, ent->d_name);
struct stat st;
if(stat(filename, &st) == 0 && S_ISREG(st.st_mode))
{
// It's a regular file - process it
}
}
}
通过在完整文件路径上调用stat(2)
并使用S_ISxxx
宏检查st_mode
字段来验证它是常规文件(而不是目录或其他类型的特殊文件)是个好主意。 请注意, readdir
返回的DIR
结构的d_type
成员并不总是受支持,因此依赖它不是一个好主意。
或者,您可以使用glob(3)
函数代替使用opendir
, readdir
和closedir
:
glob_t globbuf;
if(glob("/path/to/dir/*.txt", 0, NULL, &globbuf) == 0)
{
int i;
for(i = 0; i < globbuf.gl_pathc; i++)
process_filename(globbuf.gl_pathv[i]);
}
globfree(&globbuf);
@BartFriedrich指出了glob()
函数,但他没有举例说明它的用法。 非常简短(并且完全未经测试)你可能会尝试这样的事情
#include <glob.h>
#include <stdio.h>
void glob_example() {
glob_t g;
int i;
glob("*.txt", 0, NULL, &g);
for (i = 0; i < g.gl_pathc)
printf("matched: %s\n", g.pathv[i]);
globfree(&g)
}
glob()
实际上是一个相当复杂的函数,对于更一般的文件匹配要求,我可能不会使用它,但它确实有效地处理了你的问题。 有关更多信息,请查看Linux机器上的man glob
或在线查看手册页 。
你可以用函数写一个endswith:
int endswith (const char *name, const char *suffix)
只需在后缀中执行反向循环(从结尾开始)并检查每个char是否相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.