使用 stdlib.c 中的 qsort() 根据每个 *char 中的第 3 个字母对 C 中的字符串数组进行排序



我有一个这样的字符数组*

aob3l
gou5!
oib1k
llp6d

每 3 个索引一个数字。

我想使用 qsort(( 根据这些数字对该列表进行排序。

排序列表如下所示

oib1k
aob3l
gou5!
llp6d

这就是我尝试实现它的方式。

qsort(string_mix, (size_t) (k - 1), sizeof(char), compare_at3);

我的compare_at3函数如下所示

int compare_at3(const void* a, const void* b){
    static int k = 1;
    const char *ia = a;
    const char *ib = b;
    printf("In compare_at3 %d itern", k++);
    return ((ia[3] - '0') - (ib[3] - '0'));
}

我的问题是,

我做错了什么才能得到 SIGSEGV 段错误错误?

我最好的猜测是,这条线const char *ia = a;没有做我认为它正在做的事情。

我在*ia中使用*,因此我可以下标int作为其索引,但也许*ia不像aob3l那样char*

编辑1:对不起,我没有提到string_mix到底是什么。

它是问题中那些字符串的 2D 数组,定义为

char* string_mix[MAX_NO_OF_STRINGS]

char s1_formatted[strlen(s1)];
char s2_formatted[strlen(s2)];
formatted(s1, s1_formatted);
formatted(s2, s2_formatted);
char s1_s[26][MAX_LEN_A];
char s2_s[26][MAX_LEN_B];
for(char ch = 'a'; ch <= 'z'; ch++) {
    sprintf(s1_s[ch - 'a'], "%c%d%s", ch, s1_n[ch - 'a'], t_stringer1[ch - 'l']);
    sprintf(s2_s[ch - 'a'], "%c%d%s", ch, s2_n[ch - 'a'], fs_stringer1[ch - 'o')]);
}
char* string_mix[MAX_NO_OF_STRINGS];
int k = 0;
for(int i = 0; i < 26; i++){
    if(s1_s[i][3] - '0' != 0){
        string_mix[k] = s1_s[i];
        k++;
    }
    else if(s2_s[i][3] - '0' != 0){
        string_mix[k] = s2_s[i];
        k++;
    }
}

qsort的调用不正确。第三个参数应该是每个元素的大小。正确的调用可能是:

qsort(string_mix, (size_t) (k - 1), sizeof *string_mix, compare_at3);

或者,如果您愿意,并假设string_mixchar*数组:

qsort(string_mix, (size_t) (k - 1), sizeof (char*), compare_at3);

string_mix是一个指针数组 - 每个数组元素都是一个指针。 qsort()调用需要传递元素的大小。@Klas 林德巴克

void qsort(void *base, size_t nmemb, size_t size, 
    int (*compar)(const void *, const void *));
char* string_mix[MAX_NO_OF_STRINGS];
// qsort(string_mix, (size_t) (k - 1), sizeof(char), compare_at3);
// I suppose k-1 represents the count of elements used 
size_t number_of_elements = k - 1;
qsort(string_mix, number_of_elements, sizeof string_mix[0], compare_at3);

我做错了什么才能得到 SIGSEGV 段错误错误?

比较函数中假定的类型错误。

比较函数接收 2 个指针。 每个都是指向数组元素的指针。 在 OP 的情况下,这是一个指向指针的指针。

int compare_at3(const void* a, const void* b){
  static int k = 1;
  printf("In compare_at3 %d itern", k++);
  // const char *ia = a;
  const char **ia = (const char **) a;
  const char **ib = (const char **) b;
  const char *sa = *ia;
  const char *sb = *ib;
  // Code could insure sa, sb are long enough
  if (sa[0] == '' || sa[1] == '' || sa[2] == '') Handle_OddCase();
  if (sb[0] == '' || sb[1] == '' || sb[2] == '') Handle_OddCase();
  // The classic compare indium is below, it never overflows.
  return (sa[3] > sb[3]) - (sa[3] < sb[3]);
}

注意:关于OP评论"它是问题中定义的字符串的2D数组"。 string_mix最好描述为一维指针数组。

char* string_mix[MAX_NO_OF_STRINGS];

您将 void 指针转换为 char 指针并访问索引 3,而对内存一无所知,char 指针指向函数内部。这是不好的风格,很可能是你的SIGSEGV的原因,因为你无法访问ia[3]。

此外,你说,你想按照第三个字母排序......这将是 IA[2],如果 IA 是指向 char 数组的正确指针。

请发布您的代码...你是如何创建 char* 数组的?

最新更新