数字冒泡排序动态创建的结构数组
Numerically bubble sort a dynamically created struct array
我一直在想办法解决这个问题,但现在我束手无策了。
This 是我能找到的与我的问题最相关的 link,但它无济于事,因为该结构是单个字段,因此可以使用 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]
,但我永远无法将其编译干净。
#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);
}
问题很少:
在下面的代码中:
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;
我一直在想办法解决这个问题,但现在我束手无策了。
This 是我能找到的与我的问题最相关的 link,但它无济于事,因为该结构是单个字段,因此可以使用 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]
,但我永远无法将其编译干净。
#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);
}
问题很少:
在下面的代码中:
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;