簡體   English   中英

無法正確排序2D字符數組

[英]Unable to sort 2d character array correctly

我最多輸入100個字符串並將其歸檔,並將它們放入2D字符數組中。 STRING_LEN = 1000

char** read_from_file(char* fname, int * size)  {

    FILE *fp = fopen(fname, "r");

    int lines = 0;
    while(fscanf(fp, "%s", buff) != EOF) {
        lines++;
    }
    *size = lines;
    if(*size > 100) {
        *size = 100;
    }

    rewind(fp);

    char** file_array = malloc(*size * sizeof(char*));

        int counter;
        for(counter = 0; counter < *size; counter++) {
            file_array[counter] = malloc((STRING_LEN + 1) * sizeof(char));
        }
    for(counter = 0; counter < *size; counter++) {
           fscanf(fp, "%s", &file_array[counter]);
        }

    fclose(fp);
    return file_array;
}

快速排序將按字符串長度排序。

void quick_sort(char** words, int first, int last) {

    int pivot, j, i;
    char *temp = malloc((STRING_LEN + 1)* sizeof(char));

    if(first < last) {
        pivot = first;
        i = first;
        j = last;

        while(i < j) {
            while(strlen(&words[i]) <= strlen(&words[pivot]) && i < last)
                i++;
            while(strlen(&words[j]) > strlen(&words[pivot]))
                j--;

                if(i < j) {
                    strcpy(temp, &words[i]);
                    strcpy(&words[i], &words[j]);
                    strcpy(&words[j], temp);
                }
        }

        strcpy(temp, &words[pivot]);
        strcpy(&words[pivot], &words[j]);
        strcpy(&words[j], temp);
        free(temp);
        quick_sort(words, first, j-1);
        quick_sort(words, j+1, last);
    }
}

快速排序功能將對某些文件正確運行,但對於其他文件,例如,信息會失真。 檔案內容

car 
x 
house 
door 
ash 
a 
elephantback 
back

快速排序后

x 
a 
ash 
car 
back 
door 
house 
elephanthouse

如您所見,最后一個單詞已被重新排列,如果文件中包含更多單詞,則該單詞會變得更糟。 為什么strcpy這樣將單詞組合在一起?

您的排序函數有未定義的行為 :表達式&words[j]返回指向存儲在words[j]處的指針的指針,即它是char **類型而不是char * 刪除所有那些地址運算符,並僅使用words[j]來獲得指向該字符串的指針。

這里的問題是您要將字符串從一個數組復制到另一個數組,但是每個數組都有足夠的空間容納它包含的字符串。 因此,例如,如果您嘗試將5個字符串復制到僅分配了3個字符的空間中,則會超出分配的內存,從而導致未定義的行為。

與其復制完整的字符串,不如復制指針:

temp = words[i];
words[i] = words[j];
words[j] = temp;
...
temp = words[pivot];
words[pivot] = words[j];
words[j] = temp;

編輯:

顯然我想念所有字符串都分配了相同(大量)的空間。 因此,這不是未定義行為的原因。 正如約阿希姆·皮勒博格(Joachim Pileborg)在回答中提到的,使用&words[j]類的表達式是根本原因。

盡管如此,如上所述,交換指針比復制實際的字符串更有效,並且由於它可以處理相同的錯誤代碼行,因此仍然可以解決此問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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