简体   繁体   English

无法正确排序2D字符数组

[英]Unable to sort 2d character array correctly

I take in a maximum of 100 strings from and file and place them into a 2d character array. 我最多输入100个字符串并将其归档,并将它们放入2D字符数组中。 STRING_LEN = 1000 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;
}

Quick sort will sort by string length. 快速排序将按字符串长度排序。

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

The quick sort function will work correctly for some files but for others the information is distorted for example. 快速排序功能将对某些文件正确运行,但对于其他文件,例如,信息会失真。 File content 档案内容

car 
x 
house 
door 
ash 
a 
elephantback 
back

After quick sort 快速排序后

x 
a 
ash 
car 
back 
door 
house 
elephanthouse

As you can see the last word has been rearranged and gets worse if the file has more words. 如您所见,最后一个单词已被重新排列,如果文件中包含更多单词,则该单词会变得更糟。 Why has strcpy combined words together like this? 为什么strcpy这样将单词组合在一起?

You have undefined behavior in your sorting function: The expression &words[j] returns a pointer to the pointer stored at words[j] , ie it's the type char ** and not char * . 您的排序函数有未定义的行为 :表达式&words[j]返回指向存储在words[j]处的指针的指针,即它是char **类型而不是char * Remove all those address-of operator, and use only words[j] to get a pointer to the string. 删除所有那些地址运算符,并仅使用words[j]来获得指向该字符串的指针。

The problem here is that you're copying strings from one array to another, but each array has just enough space for the string it contains. 这里的问题是您要将字符串从一个数组复制到另一个数组,但是每个数组都有足够的空间容纳它包含的字符串。 So if for example you try to copy a 5 character string to a space with only 3 characters allocated, you overrun the allocated memory, leading to undefined behavior. 因此,例如,如果您尝试将5个字符串复制到仅分配了3个字符的空间中,则会超出分配的内存,从而导致未定义的行为。

Rather than copying the full strings around, just copy the pointers: 与其复制完整的字符串,不如复制指针:

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

EDIT: 编辑:

Apparently I missed that all strings are allocated the same (large) amount of space. 显然我想念所有字符串都分配了相同(大量)的空间。 So that's not the cause of the undefined behavior. 因此,这不是未定义行为的原因。 As Joachim Pileborg mentioned in his answer, using expressions like &words[j] was the root cause. 正如约阿希姆·皮勒博格(Joachim Pileborg)在回答中提到的,使用&words[j]类的表达式是根本原因。

Still, swapping the pointers as I mentioned above is more efficient than copying the actual strings, and because it addresses the same erroneous lines of code it will still fix the problem. 尽管如此,如上所述,交换指针比复制实际的字符串更有效,并且由于它可以处理相同的错误代码行,因此仍然可以解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM