c - 数字冒泡排序动态创建的结构数组

标签 c struct memcpy bubble-sort

我一直想弄清楚这个问题,但现在我已经束手无策了。

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],但我永远无法将其编译干净。

最佳答案

#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);
}

关于c - 数字冒泡排序动态创建的结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51582290/

相关文章:

c++ - 数组在通过引用传递给函数之前和之后显示不同的地址

c - 屏蔽最高有效位

c - 在 C 中将 sizeof() 与指向结构的指针一起使用

c - 奇怪的 malloc 行为

c++ - 最终使用 NEON Copy 但不使用 memcpy 的 ARM Linux 内存碎片

c - 使用 memcpy 将字符串复制到字符数组时出现段错误

c - 在 C "invalid operands to binary expression (' size_t'(又名 'unsigned long' )和 'char *' )中重新创建 strlcat 函数”

c - 为什么我在获取时间戳时得到负值?

将 uint16 转换为 jint 并返回 JNI

c - Typedef、标记和未标记结构以及不兼容的指针类型