如何在C中正确排序字符串?

时间:2009-11-05 00:04:33

标签: c string sorting

这是我的代码:

#include <stdio.h>
#include <string.h>
#include <errno.h>

int cmp(const void *a, const void *b) {
    const char **ia = (const char **)a;
    const char **ib = (const char **)b;
    return strcmp(*ia, *ib);
}

void print_array(char **array, size_t len) {
    size_t i;
    for(i=0; i<len; i++) {
        printf("%s, ", array[i]);
    }
    putchar('\n');
}

int main(int argc, char *argv[]) {

        char *strings[] = { "z1.doc", "z100.doc",  "z2.doc", "z3.doc", "z20.doc"};
        size_t strings_len = sizeof(strings) / sizeof(char *);
        print_array(strings, strings_len);
        qsort(strings, strings_len, sizeof(char *), cmp);
        print_array(strings, strings_len);

        system("PAUSE");
        return 1;
}

实际输出是

z1.doc, z100.doc, z2.doc, z20.doc, z3.doc

我希望它是

z1.doc, z2.doc, z3.doc, z20.doc, z100.doc

出了什么问题?

3 个答案:

答案 0 :(得分:4)

实际输出正确,字符串“z100.doc”小于“z2.doc”。 strcmp逐字符地比较,当它达到小于'2'的'1'并且它停在那里时,所以z100&lt; Z2。

如果您将文件命名为z001.doc,z002.doc,z003.doc,z020.doc,z100.doc,它将按您希望的方式排序。

答案 1 :(得分:3)

将比较器更改为:

return (atoi(*ib + 1) - atoi(*ia + 1));

答案 2 :(得分:1)

您需要自然排序算法,而不是默认提供的ASCIIbetical排序算法。请参阅Jeff's blog entry以获取有关此问题的长篇大论,以及与此自然算法实现的一些不错的链接。正如警告一样,正确的实现(与你接受的hacky回答相反)是相当复杂的,所以不要试图自己实现它,拿别人的(希望是公共领域或自由的)许可)实施和使用它。