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

Using qsort() from stdlib.c to sort an array of strings in C according to the 3rd letter in each *char

我有一个像这样的 char* 数组

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 iter\n", k++);

    return ((ia[3] - '0') - (ib[3] - '0'));
}

我的问题是,

我做错了什么导致 SIGSEGV 段错误?

我最好的猜测是这条线 const char *ia = a; 没有按照我的想法去做。

我在 *ia 中使用 * 所以我可以下标 int 作为它的索引,但也许 *ia 不像 char* aob3l.

EDIT1:抱歉,我没有提到 string_mix 到底是什么。

它是问题中定义的那些字符串的二维数组

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++;
    }
}

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

此外,你说,你想根据第 3 个字母排序...这将是 ia[2],如果 ia 是指向 char 数组的正确指针。

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

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()调用需要传递元素的大小。

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

what am I doing wrong to get SIGSEGV segfault errors?

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

比较函数接收到2个指针。每个都是指向数组元素的指针。在 OP 的例子中,这是一个指向指针的指针。

int compare_at3(const void* a, const void* b){
  static int k = 1;
  printf("In compare_at3 %d iter\n", 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] == '[=11=]' || sa[1] == '[=11=]' || sa[2] == '[=11=]') Handle_OddCase();
  if (sb[0] == '[=11=]' || sb[1] == '[=11=]' || sb[2] == '[=11=]') Handle_OddCase();

  // The classic compare indium is below, it never overflows.
  return (sa[3] > sb[3]) - (sa[3] < sb[3]);
}

注意:关于 OP 评论 "It's a 2D array of those strings in the question defined like"。 string_mix 最好描述为一维指针数组。

char* string_mix[MAX_NO_OF_STRINGS];