我试图弄清楚这一点,但是现在我机智了。
This是我可以找到的与问题最相关的链接,但由于结构是单个字段,因此无济于事,因此可以使用strcpy而不是memcpy(对于具有多个字段的结构)。
这是最后的代码更改,这是我唯一可以完全编译的代码。
#include <stdio.h>
#include <errno.h>
#include <libgen.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#define DIR_SIZE 400
#define FILE_SIZE 500
struct _data
{
long int size;
char file[FILE_SIZE + 1];
};
int fill_struct (struct _data **data, char *dir);
void sort_struct (struct _data **data, int count);
// Used for error reporting.
char *program_name = NULL;
void sort_struct (struct _data **data, int count)
{
// Declare variables.
int i = {0};
int j = {0};
struct _data temp = {0};
// Bubble sort struct.
for (i = 0; i < count; i++)
{
for (j = 0; j < count - i; j++)
{
if ((*data[j]).size > (*data[j + 1]).size)
{
memcpy(&temp, (&data)[j], sizeof(struct _data));
memcpy(&data[j], &data[j + 1], sizeof(struct _data));
memcpy(&data[j + 1], &temp, sizeof(struct _data));
}
}
}
}
int main (int argc, char *argv[])
{
// Declare variables.
int count = {0};
struct _data *data = NULL;
// Get program name for error reporting.
program_name = basename(argv[0]);
// Check for correct number of arguments.
if(argc != 2)
{
fprintf(stderr, "usage: %s DIRECTORY\n", program_name);
exit(EXIT_FAILURE);
}
// Get all file info from directory.
count = fill_struct(&data, argv[1]);
// Sort the struct based on size.
sort_struct(&data, count);
// Free allocated memory.
free(data);
// Exit gracefully.
exit(EXIT_SUCCESS);
}
int fill_struct (struct _data **data, char *dir)
{
// Declare variables.
int count = 0;
DIR *dp = NULL;
struct dirent *ep = NULL;
struct _data *temp = NULL;
struct stat file_info = {0};
char file[FILE_SIZE + 1] = {0};
// Open directory for reading.
if((dp = opendir(dir)) == NULL)
{
fprintf(stderr, "%s: fill_struct error: opendir failed (%s) (%s)\n", program_name, dir, strerror(errno));
exit(EXIT_FAILURE);
}
// Loop through all entries.
while((ep = readdir(dp)) != NULL)
{
// Skip everything but files.
if(ep->d_type != DT_REG)
continue;
// Increase count.
count++;
// Build filename path.
strcpy(file, dir);
// Add slash if needed.
if(dir[strlen(dir) - 1] != '/')
strcat(file, "/");
// Add filename.
strcat(file, ep->d_name);
// Get file info.
if(stat(file, &file_info) == -1)
{
fprintf(stderr, "%s: fill_struct error: stat failed (%s) (%s)\n", program_name, file, strerror(errno));
exit(EXIT_FAILURE);
}
// Allocate more memory for additional records.
if((temp = realloc(*data, sizeof(struct _data) * count)) == NULL)
{
fprintf(stderr, "%s: fill_struct error: realloc failed\n", program_name);
free(*data);
exit(EXIT_FAILURE);
}
// Store file data.
strcpy(temp[count - 1].file, file);
temp[count - 1].size = file_info.st_size;
// Change pointer on success.
*data = temp;
}
// Return total count of records.
return(count);
}
尽管可以干净地编译,但是运行它会导致Segmentation fault (core dumped)
之前,我尝试使用(*data)[x]
而不是(&data)[x]
,但是我永远无法使它干净地编译。
答案 0 :(得分:3)
#include <stddef.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define FILE_SIZE 500
struct _data
{
long int size;
char file[FILE_SIZE + 1];
};
void sort_struct (struct _data *data, size_t count)
{
bool swapped;
struct _data temp;
do {
swapped = false;
for (size_t i = 0; i < count - 1; ++i)
{
if (data[i].size > data[i + 1].size)
{
memcpy(&temp, &data[i], sizeof(*data));
memcpy(&data[i], &data[i + 1], sizeof(*data));
memcpy(&data[i + 1], &temp, sizeof(*data));
swapped = true;
}
}
} while (swapped);
}
int main(void)
{
_data foo[]{
{10, "theodor"},
{13, "anja"},
{ 9, "robert"},
{11, "nadine"},
{15, "lucy"}
};
for (size_t i = 0; i < sizeof(foo) / sizeof(*foo); ++i)
printf("%li: \"%s\"\n", foo[i].size, foo[i].file);
sort_struct(foo, sizeof(foo) / sizeof(*foo));
putchar('\n');
for (size_t i = 0; i < sizeof(foo) / sizeof(*foo); ++i)
printf("%li: \"%s\"\n", foo[i].size, foo[i].file);
}
答案 1 :(得分:2)
有几个问题:
if ((*data[j]).size > (*data[j + 1]).size)
{
memcpy(&temp, (&data)[j], sizeof(struct _data));
memcpy(&data[j], &data[j + 1], sizeof(struct _data));
memcpy(&data[j + 1], &temp, sizeof(struct _data));
}
data
是指向指针的指针。 data[j]
是一个指针,因此&data [j]返回指向指针的指针,而不仅仅是memcpy
期望得到的指针。
当您有指向指针的指针时,应首先将其转换为前缀为*
的指针,然后将其用作常规指针。为避免发生尺寸错误,请在括号内使用它,例如:(*data)
应该是:
if ((*data)[j].size > (*data)[j + 1].size)
{
memcpy(&temp, (*data)[j], sizeof(struct _data));
memcpy((*data)[j], (*data)[j + 1], sizeof(struct _data));
memcpy((*data)[j + 1], &temp, sizeof(struct _data));
}
您没有2维数组,并且您没有更改分配。因此,您不应该将指针指向混乱。 因此该函数应声明为:
void sort_struct (struct _data *data, int count)
memcpy
,例如:temp = data[j];
data[j] = data[j+1];
data[j+1]= temp;
temp = (*data)[j];
(*data)[j] = (*data)[j+1];
(*data)[j+1]= temp;