C - 将文件夹和子文件夹中的所有 wav 文件路径放入具有递归函数的字符串数组中
C - Putting all the wav file paths from a folder and subfolder into an array of string with a recursive function
我在使用下面的代码时遇到了一些问题,它应该将文件夹的路径作为输入(在我的例子中 "pack"),并将路径放入它可以在文件夹中找到的每个 .wav 文件或在子文件夹中放入字符串数组。
您在下面看到的代码崩溃了。
在向你们寻求帮助之前,我自己进行了搜索,当尝试为该文件夹的第一个文件重新分配时,崩溃似乎附加在第二个子文件夹中
我正在测试的文件夹结构是这样的:
pack
├── _subfolder1
| ├── wavefile1.wav
| ├── wavefile2.wav
| └── wavefile3.wav
├── _subfolder2
| └── wavefile4.wav
├── _subfolder3
| ├── wavefile5.wav
| └── wavefile6.wav
代码:
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
void find_dir_content(char* path, char** filepathlist, int* size)
{
DIR* d = opendir(path);
if(d == NULL)
return;
struct dirent* dir;
while((dir = readdir(d)) != NULL)
{
int isdir = 0;
DIR* tmp;
char f_path[255];
sprintf(f_path, "%s/%s", path, dir->d_name);
if((tmp = opendir(f_path))) {
closedir(tmp);
isdir = 1;
}
if(!isdir) {
char *dot = strrchr(dir->d_name, '.');
if (dot && !strcmp(dot, ".wav")){
char** tmp = realloc(filepathlist, sizeof(char*) * ((*size) + 1));
if (tmp == NULL)
{
return;
}
else
{
filepathlist = tmp;
}
char d_path[256];
sprintf(d_path, "%s/%s", path, dir->d_name);
filepathlist[*size] = d_path;
//printf("%d : %s\n", *size, filepathlist[*size]);
(*size)++;
}
}
else if(isdir && strcmp(dir->d_name, ".") != 0 &&
strcmp(dir->d_name, "..") != 0)
{
char d_path[256];
sprintf(d_path, "%s/%s", path, dir->d_name);
//printf("%s\n", d_path);
find_dir_content(d_path, filepathlist, size);
}
}
closedir(d);
}
int main(int argc, char** argv)
{
int sizefilepathlist = 0;
char** filepathlist = (char**) malloc(0*sizeof(char*));
find_dir_content("pack", filepathlist, &sizefilepathlist);
for(int i = 0; i< sizefilepathlist; i++){
printf("%s", filepathlist[i]);
}
return 0;
}
编辑:我在 windows,我将 codelite 与 minGW(gcc) 一起使用,没有错误消息,windows 只是给我旧的 "has stopped working" 错误。
正如@unwind 在评论中指出的那样:
You're storing the address of a local variable. That will get you undefined behavior. You must dynamically allocate room for the path itself, not just the pointer to it.
最小的变化是更改行:
filepathlist[*size] = d_path;
到
filepathlist[*size] = strdup(d_path); // d_path will go out of scope - copy the string to dynamically allocated memory.
确保 #include <string.h>
获得 strdup
的原型。
编辑:
另一个问题是,当您 realloc(filepathlist)
时, main
中的变量仍然指向旧位置。这可以通过让 find_dir_content
return 当前位置 filepathlist
:
来解决
char **filepathlist(...) {
...
return filepathlist;
}
主要是:
filepathlist = find_dir_content("pack", filepathlist, &sizefilepathlist);
我在使用下面的代码时遇到了一些问题,它应该将文件夹的路径作为输入(在我的例子中 "pack"),并将路径放入它可以在文件夹中找到的每个 .wav 文件或在子文件夹中放入字符串数组。
您在下面看到的代码崩溃了。
在向你们寻求帮助之前,我自己进行了搜索,当尝试为该文件夹的第一个文件重新分配时,崩溃似乎附加在第二个子文件夹中
我正在测试的文件夹结构是这样的:
pack
├── _subfolder1
| ├── wavefile1.wav
| ├── wavefile2.wav
| └── wavefile3.wav
├── _subfolder2
| └── wavefile4.wav
├── _subfolder3
| ├── wavefile5.wav
| └── wavefile6.wav
代码:
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
void find_dir_content(char* path, char** filepathlist, int* size)
{
DIR* d = opendir(path);
if(d == NULL)
return;
struct dirent* dir;
while((dir = readdir(d)) != NULL)
{
int isdir = 0;
DIR* tmp;
char f_path[255];
sprintf(f_path, "%s/%s", path, dir->d_name);
if((tmp = opendir(f_path))) {
closedir(tmp);
isdir = 1;
}
if(!isdir) {
char *dot = strrchr(dir->d_name, '.');
if (dot && !strcmp(dot, ".wav")){
char** tmp = realloc(filepathlist, sizeof(char*) * ((*size) + 1));
if (tmp == NULL)
{
return;
}
else
{
filepathlist = tmp;
}
char d_path[256];
sprintf(d_path, "%s/%s", path, dir->d_name);
filepathlist[*size] = d_path;
//printf("%d : %s\n", *size, filepathlist[*size]);
(*size)++;
}
}
else if(isdir && strcmp(dir->d_name, ".") != 0 &&
strcmp(dir->d_name, "..") != 0)
{
char d_path[256];
sprintf(d_path, "%s/%s", path, dir->d_name);
//printf("%s\n", d_path);
find_dir_content(d_path, filepathlist, size);
}
}
closedir(d);
}
int main(int argc, char** argv)
{
int sizefilepathlist = 0;
char** filepathlist = (char**) malloc(0*sizeof(char*));
find_dir_content("pack", filepathlist, &sizefilepathlist);
for(int i = 0; i< sizefilepathlist; i++){
printf("%s", filepathlist[i]);
}
return 0;
}
编辑:我在 windows,我将 codelite 与 minGW(gcc) 一起使用,没有错误消息,windows 只是给我旧的 "has stopped working" 错误。
正如@unwind 在评论中指出的那样:
You're storing the address of a local variable. That will get you undefined behavior. You must dynamically allocate room for the path itself, not just the pointer to it.
最小的变化是更改行:
filepathlist[*size] = d_path;
到
filepathlist[*size] = strdup(d_path); // d_path will go out of scope - copy the string to dynamically allocated memory.
确保 #include <string.h>
获得 strdup
的原型。
编辑:
另一个问题是,当您 realloc(filepathlist)
时, main
中的变量仍然指向旧位置。这可以通过让 find_dir_content
return 当前位置 filepathlist
:
char **filepathlist(...) {
...
return filepathlist;
}
主要是:
filepathlist = find_dir_content("pack", filepathlist, &sizefilepathlist);