【问题标题】:Sorting an Array of Struct with type Char, qsort对 Char 类型的结构数组进行排序,qsort
【发布时间】:2021-12-15 19:43:57
【问题描述】:

我遇到了 zsh: 分段错误(此错误与内存有关)我不知道它为什么会发生。我正在尝试为我的结构中的字符串创建一个比较函数。我需要程序能够按升序对字符串进行排序。

当前代码:

#include <stdio.h>
#include <string.h>
#include "stdlib.h"
# define MAX 7

typedef struct{
    double price;
    char title[60];
} game;
game gArr[MAX];

game buildGame(double num, const char *title);
void printGame(game);

int compGamesByTitle(const void * a,const void * b);

int main(){
    gArr[0] = buildGame(0.01, "Minecraft");
    gArr[1] = buildGame(22.79 , "Opus Magnum");
    gArr[2] = buildGame(7.79 , "TIS-100");
    gArr[3] = buildGame(14.99 , "Trainz");
    gArr[4] = buildGame(0 , "Code Combat");
    gArr[5] = buildGame(7.79, "Lemmings Revolution");
    gArr[6] = buildGame(64.96 , "Warcraft");

    qsort(gArr,sizeof(gArr)/sizeof(gArr[0]), sizeof(gArr[0]), compGamesByTitle);
    printf("Sorted Games:\n");
    for (int i = 0; i < MAX; i++){
        printGame(gArr[i]);
    }


    return 0;
}
int compGamesByTitle(const void *a,const void *b){
    char **aa = (char **)a;
    char **bb = (char **)b;

    return strcmp(*aa,*bb);
}

game buildGame(double num, const char *title){
    game g;
    g.price = num; strcpy(g.title, title);
    return g;
}
void printGame(game g){
    printf("Game g: %.2f, %s\n", g.price, g.title);
}

我认为问题与未分配的内存有关,但我不确定在哪里或为什么。

所需输出: 结构数组中的字符串应按字母顺序(a-z)升序排序。

【问题讨论】:

  • 您有一个game 数组,为什么要在您的compGamesByTitle 函数中转换为char**
  • 你说得对,我修改了代码;但是,现在不是分段错误,而是无法正确排序。 @UnholySheep

标签: arrays c struct char qsort


【解决方案1】:

不,您的问题与未初始化的内存无关。作为qsort 的第四个参数传递的比较函数接收指向要比较的数组元素的指针。由于您的gArrgame 对象的数组,但您在compGamesByTitle 内转换为char**,您最终会在不指向空终止字节字符串的指针上调用strcmp,调用 未定义的行为

你的比较函数应该是这样的

int compGamesByTitle(const void *a,const void *b){
    const game *aa = a;
    const game *bb = b;

    return strcmp(aa->title, bb->title);
}

【讨论】:

    【解决方案2】:

    这不是问题的答案,只是对@UnholySheep 答案的一些额外输入。

    game buildGame(double num, const char *title){
        game g;
        g.price = num; strcpy(g.title, title);
        return g;
    }
    

    应该更健壮再次长标题名称。建议

    game buildGame(double num, const char *title) {
        game g;
        g.price = num;
        g.title[0] = '\0';
        strncat(g.title, title, sizeof(g.title) - 1U);
        return g;
    }
    

    只要 game::title 仍然是一个数组。

    使用strncat 而不是strncpy 的动机是不要写出不必要的字符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 2014-07-04
      • 2021-07-16
      相关资源
      最近更新 更多