建立链接列表以存储组 ID 和文件路径的正确方法
Proper Way to Set Up a Linked List to Store a Group ID and File Path
我正在尝试创建一个链表数据结构,它允许我存储组 ID # 以及它所属的文件目录的文件路径。该程序打开当前目录并从当前目录中获取所有常规文件,输出每个文件的路径,并尝试将路径插入到链表中。对于它插入的每个文件路径,将创建一个新的 groupID(将 1 添加到之前的 groupID # 中),第一个 groupID 从 1 开始。到目前为止,这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
typedef struct FileGroups
{
int groupID;
char *path;
struct FileGroups* next;
} FileGroups;
FileGroups *head;
void insert(char *path)
{
FileGroups *temp;
temp = (FileGroups*)malloc(sizeof(FileGroups));
temp->groupID += 1;
temp->path = path;
temp->next = head;
head = temp;
temp = temp ->next;
}
void print()
{
FileGroups *temp;
temp = head;
printf("\nLinked list: \n");
while(temp!=NULL)
{
printf("%d %s\n", temp->groupID, temp->path);
temp = temp->next;
}
}
void listFilesRecursively(const char *basePath)
{
char path[1024];
struct dirent *dp;
DIR *dir = opendir(basePath);
if (!dir)
{
return;
}
while ((dp = readdir(dir)) != NULL)
{
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
{
struct stat sb;
strcpy(path, basePath);
strcat(path, "/");
strcat(path, dp->d_name);
if(stat(path, &sb) == 0 && S_ISREG(sb.st_mode))
{
printf("%s\n", path);
insert(path);
}
else
{
return;
}
}
}
closedir(dir);
}
int main()
{
listFilesRecursively(".");
print();
return 0;
}
当我去打印链表时,我得到以下输出:
在上半部分你可以看到我当前目录中的所有常规文件,下面是我的链接列表,它似乎只存储了我当前目录中列出的最后一个文件,在左边我们看到groupID # 也没有改变,而不是在添加每个文件路径时加 1,它停留在 groupID #1。任何关于我哪里出错的建议或指示将不胜感激。谢谢!
在每次迭代中,path
被覆盖并分配给列表的新元素,但您并未将字符串复制到新缓冲区。
因此,最后列表的每个元素都将指向 listFilesRecursively()
中声明的 path
,它将仅包含列出的最后一个文件
...
int GroupID = 1;
void listFilesRecursively(const char *basePath)
...
char path[1024];
...
// Here path is overwritten
strcpy(path, basePath);
strcat(path, "/");
strcat(path, dp->d_name);
...
insert(path);
void insert(char *path)
...
// This is copying only the pointer to path
temp->path = path;
您应该在插入时为路径分配一个新的缓冲区。
void insert(char *path)
{
FileGroups *temp;
temp = (FileGroups*)malloc(sizeof(FileGroups));
/**
* This should not be += 1
* Memory allocated by malloc is not initialised.
* Value at these locations are indeterminate.
*
* To know the next groupID I'm using a simple
* global variable as suggested by Serge Ballesta
* in his comment
*/
temp->groupID = GroupID++;
//------------------------------------------------------
temp->path = malloc(strlen(path)*sizeof(char));
strcpy(temp->path, path);
//------------------------------------------------------
temp->next = head;
head = temp;
temp = temp ->next;
}
你可以运行这里https://onlinegdb.com/O6cTm7Hu1
关于malloc()
我正在尝试创建一个链表数据结构,它允许我存储组 ID # 以及它所属的文件目录的文件路径。该程序打开当前目录并从当前目录中获取所有常规文件,输出每个文件的路径,并尝试将路径插入到链表中。对于它插入的每个文件路径,将创建一个新的 groupID(将 1 添加到之前的 groupID # 中),第一个 groupID 从 1 开始。到目前为止,这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
typedef struct FileGroups
{
int groupID;
char *path;
struct FileGroups* next;
} FileGroups;
FileGroups *head;
void insert(char *path)
{
FileGroups *temp;
temp = (FileGroups*)malloc(sizeof(FileGroups));
temp->groupID += 1;
temp->path = path;
temp->next = head;
head = temp;
temp = temp ->next;
}
void print()
{
FileGroups *temp;
temp = head;
printf("\nLinked list: \n");
while(temp!=NULL)
{
printf("%d %s\n", temp->groupID, temp->path);
temp = temp->next;
}
}
void listFilesRecursively(const char *basePath)
{
char path[1024];
struct dirent *dp;
DIR *dir = opendir(basePath);
if (!dir)
{
return;
}
while ((dp = readdir(dir)) != NULL)
{
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
{
struct stat sb;
strcpy(path, basePath);
strcat(path, "/");
strcat(path, dp->d_name);
if(stat(path, &sb) == 0 && S_ISREG(sb.st_mode))
{
printf("%s\n", path);
insert(path);
}
else
{
return;
}
}
}
closedir(dir);
}
int main()
{
listFilesRecursively(".");
print();
return 0;
}
当我去打印链表时,我得到以下输出:
在上半部分你可以看到我当前目录中的所有常规文件,下面是我的链接列表,它似乎只存储了我当前目录中列出的最后一个文件,在左边我们看到groupID # 也没有改变,而不是在添加每个文件路径时加 1,它停留在 groupID #1。任何关于我哪里出错的建议或指示将不胜感激。谢谢!
在每次迭代中,path
被覆盖并分配给列表的新元素,但您并未将字符串复制到新缓冲区。
因此,最后列表的每个元素都将指向 listFilesRecursively()
中声明的 path
,它将仅包含列出的最后一个文件
...
int GroupID = 1;
void listFilesRecursively(const char *basePath)
...
char path[1024];
...
// Here path is overwritten
strcpy(path, basePath);
strcat(path, "/");
strcat(path, dp->d_name);
...
insert(path);
void insert(char *path)
...
// This is copying only the pointer to path
temp->path = path;
您应该在插入时为路径分配一个新的缓冲区。
void insert(char *path)
{
FileGroups *temp;
temp = (FileGroups*)malloc(sizeof(FileGroups));
/**
* This should not be += 1
* Memory allocated by malloc is not initialised.
* Value at these locations are indeterminate.
*
* To know the next groupID I'm using a simple
* global variable as suggested by Serge Ballesta
* in his comment
*/
temp->groupID = GroupID++;
//------------------------------------------------------
temp->path = malloc(strlen(path)*sizeof(char));
strcpy(temp->path, path);
//------------------------------------------------------
temp->next = head;
head = temp;
temp = temp ->next;
}
你可以运行这里https://onlinegdb.com/O6cTm7Hu1
关于malloc()