首页 > 解决方案 > 对动态创建的结构数组进行数值冒泡排序

问题描述

我试图弄清楚这一点,但现在我束手无策。

是我能找到的与我的问题最相关的链接,但它没有帮助,因为结构是单个字段,因此可以使用 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],但我永远无法让它干净地编译。

标签: cstructmemcpybubble-sort

解决方案


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

推荐阅读