[英]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
每個第三個索引都有一個數字。
我想使用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 segfault錯誤,我做錯了什么?
我最好的猜測是,這行const char *ia = a;
沒有按照我認為的去做。
我在*ia
使用*
,因此我可以將int
下標為其索引,但也許*ia
不是像aob3l
這樣的char*
。
EDIT1:對不起,我沒有提到確切的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_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);
發生SIGSEGV segfault錯誤,我做錯了什么?
比較函數中假定錯誤的類型。
比較函數接收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] == '\0' || sa[1] == '\0' || sa[2] == '\0') Handle_OddCase();
if (sb[0] == '\0' || sb[1] == '\0' || sb[2] == '\0') 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是指向char數組的正確指針,則它將為ia [2]。
請發布您的代碼...您是如何創建char *數組的?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.