簡體   English   中英

使用stdlib.c中的qsort()根據每個* char中的第三個字母對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

每個第三個索引都有一個數字。

我想使用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_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);

發生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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM