在特定条件下迭代文件夹的文件
Iterate on files of a folder, with specific condition
将 this solution 与 dirent.h 结合使用,我正在尝试迭代当前文件夹的特定文件(那些具有 .wav
扩展名 和 以 3 位数字开头)使用以下代码:
(重要说明:因为我使用 MSVC++ 2010,似乎我不能使用 #include <regex>
,而且我也不能使用 this 因为没有 C++11支持)
DIR *dir;
struct dirent *ent;
if ((dir = opendir (".")) != NULL) {
while ((ent = readdir (dir)) != NULL) {
printf ("%s\n", ent->d_name);
//if substr(ent->d_name, 0, 3) ... // what to do here to
// check if those 3 first char are digits?
// int i = susbtr(ent->d_name, 0, 3).strtoi(); // error here! how to parse
// the 3 first char (digits) as int?
// if susbtr(ent->d_name, strlen(ent->d_name)-3) != "wav" // ...
}
closedir (dir);
} else {
perror ("");
return EXIT_FAILURE;
}
如何使用 C+11 支持不完全存在的 MSVC++2010 执行这些测试?
好的,这是一个解决方案
#include <stdio.h>
#include <string.h>
int
main(void)
{
const char *strings[] = {"123.wav", "1234 not-good.wav", "456.wav", "789.wav", "12 fail.wav"};
int i;
int number;
for (i = 0 ; i < sizeof(strings) / sizeof(*strings) ; ++i)
{
size_t length;
int count;
const char *pointer;
if ((sscanf(strings[i], "%d%n", &number, &count) != 1) || (count != 3))
continue;
length = strlen(strings[i]);
if (length < 4)
continue;
pointer = strings[i] + length - 4;
if (strncasecmp(pointer, ".wav", 4) != 0)
continue;
printf("%s matches and number is %d\n", strings[i], number);
}
return 0;
}
如您所见,scanf()
检查字符串开头是否有整数,也跳过任何可能的白色 space 字符,然后捕获扫描的字符数,如果等于 3
则它继续检查扩展名。
如果您使用的是 Windows,请将 strncasecmp()
替换为 _strnicmp()
。
您实际上不会检查 wav
扩展名,只是文件名将以这 3 个字母结尾...
C 库中没有 substr
这样的函数来从字符串中提取切片。
您应该检查文件名长度是否至少为 7:strlen(ent->d_name) >= 7
,然后使用 <ctype.h>
中的 isdigit
函数检查前 3 个字符是否为数字而不是第四个字符最后使用 strcmp
或更好的 strcasecmp
将文件名的最后 4 个字符与 ".wav"
进行比较。后者在微软的世界里可能被称为_stricmp
。如果这些都不可用,请使用 tolower
将最后 3 个字符与 'w'
、'a'
和 'v'
.
进行比较
这里是放宽要求的实现(任意位数):
#include <ctype.h>
#include <stdlib.h>
...
DIR *dir;
struct dirent *ent;
if ((dir = opendir(".")) != NULL) {
while ((ent = readdir(dir)) != NULL) {
char *name = ent->d_name;
size_t length = strlen(name);
if (length >= 5 &&
isdigit(name[0]) &&
name[length-4] == '.' &&
tolower(name[length-3]) == 'w' &&
tolower(name[length-2]) == 'a' &&
tolower(name[length-1]) == 'v') {
int num = atoi(name);
printf("%s -> %d\n", name, num);
/* do your thing */
}
}
closedir(dir);
} else {
perror ("");
return EXIT_FAILURE;
}
将 this solution 与 dirent.h 结合使用,我正在尝试迭代当前文件夹的特定文件(那些具有 .wav
扩展名 和 以 3 位数字开头)使用以下代码:
(重要说明:因为我使用 MSVC++ 2010,似乎我不能使用 #include <regex>
,而且我也不能使用 this 因为没有 C++11支持)
DIR *dir;
struct dirent *ent;
if ((dir = opendir (".")) != NULL) {
while ((ent = readdir (dir)) != NULL) {
printf ("%s\n", ent->d_name);
//if substr(ent->d_name, 0, 3) ... // what to do here to
// check if those 3 first char are digits?
// int i = susbtr(ent->d_name, 0, 3).strtoi(); // error here! how to parse
// the 3 first char (digits) as int?
// if susbtr(ent->d_name, strlen(ent->d_name)-3) != "wav" // ...
}
closedir (dir);
} else {
perror ("");
return EXIT_FAILURE;
}
如何使用 C+11 支持不完全存在的 MSVC++2010 执行这些测试?
好的,这是一个解决方案
#include <stdio.h>
#include <string.h>
int
main(void)
{
const char *strings[] = {"123.wav", "1234 not-good.wav", "456.wav", "789.wav", "12 fail.wav"};
int i;
int number;
for (i = 0 ; i < sizeof(strings) / sizeof(*strings) ; ++i)
{
size_t length;
int count;
const char *pointer;
if ((sscanf(strings[i], "%d%n", &number, &count) != 1) || (count != 3))
continue;
length = strlen(strings[i]);
if (length < 4)
continue;
pointer = strings[i] + length - 4;
if (strncasecmp(pointer, ".wav", 4) != 0)
continue;
printf("%s matches and number is %d\n", strings[i], number);
}
return 0;
}
如您所见,scanf()
检查字符串开头是否有整数,也跳过任何可能的白色 space 字符,然后捕获扫描的字符数,如果等于 3
则它继续检查扩展名。
如果您使用的是 Windows,请将 strncasecmp()
替换为 _strnicmp()
。
您实际上不会检查 wav
扩展名,只是文件名将以这 3 个字母结尾...
C 库中没有 substr
这样的函数来从字符串中提取切片。
您应该检查文件名长度是否至少为 7:strlen(ent->d_name) >= 7
,然后使用 <ctype.h>
中的 isdigit
函数检查前 3 个字符是否为数字而不是第四个字符最后使用 strcmp
或更好的 strcasecmp
将文件名的最后 4 个字符与 ".wav"
进行比较。后者在微软的世界里可能被称为_stricmp
。如果这些都不可用,请使用 tolower
将最后 3 个字符与 'w'
、'a'
和 'v'
.
这里是放宽要求的实现(任意位数):
#include <ctype.h>
#include <stdlib.h>
...
DIR *dir;
struct dirent *ent;
if ((dir = opendir(".")) != NULL) {
while ((ent = readdir(dir)) != NULL) {
char *name = ent->d_name;
size_t length = strlen(name);
if (length >= 5 &&
isdigit(name[0]) &&
name[length-4] == '.' &&
tolower(name[length-3]) == 'w' &&
tolower(name[length-2]) == 'a' &&
tolower(name[length-1]) == 'v') {
int num = atoi(name);
printf("%s -> %d\n", name, num);
/* do your thing */
}
}
closedir(dir);
} else {
perror ("");
return EXIT_FAILURE;
}