使用 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_mix
是 char*
的数组:
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];
我有一个像这样的 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_mix
是 char*
的数组:
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];