排序函数

时间:2016-01-11 21:09:12

标签: c sorting segmentation-fault qsort

作为一个家庭作业,我编写了这个应该使用qsort_r对控制台输入进行排序的程序(这是我无法改变的一件事,我们需要使用qsort_r)。我们应该实现三种不同的排序功能; compVal通常按值对输入进行排序,compOnes按照其位值包含的1s量对输入进行排序,compBitSeq按最长位序列对它们进行排序(并且排序应该双向工作,因此方向变量)。

正常排序功能正常。但是,我不能让compOnes和compBitSeq工作。我已经尝试了自己的辅助函数countOnes和bitSequence;他们似乎工作得很好,做我期望他们做的事情。但是,当我尝试调整它时,整个程序会给我一个分段错误。

由于我还没有使用指针超级安全​​,我无法确定这里有什么问题。我假设将函数传递给函数可能存在问题,并且我没有正确传递所有值,但我不确定如何做到这一点?我已经尝试将所有内容放在一个函数中,这非常不优雅,因为我必须执行相同的循环来查找acount和bcount,但这也无效。 qsort_r也削减了我的灵活性,因为我必须坚持使用该函数所需的数据类型。

我现在已经摆脱了分段错误,将函数strcomp与memcmp交换就行了!现在我确实得到了一个输出,但它不是那么理想,我不能在这里得到什么错误。我已经用几个值尝试了我的countOnes和bitSeq函数,输出告诉我正在确定的值是正确的(我在我的代码中注释了所以我知道它应该是什么顺序)。但排序似乎是完全随机的(好吧它可能不是,但我真的不知道它的排序......我觉得每次输出都不同,即使数字相同,特别是如果我以不同的顺序输入它们,即使是完全正常的排序顺序。

如果这有帮助,我现在修改了我的功能,以便打印他们正在比较的数字,并且......这是一些负数: 编号a:-41,编号b:-39,顺序:-2 数字a:-34,数字b:-31,顺序:-3 编号a:-36,编号b:-34,顺序:-2 编号a:-41,编号b:-36,顺序:-5 数字a:-39,数字b:-36,顺序:-3 3,15,7,97,32

(显然,这些数字随着它们的进入而出现,因为这些数值都会产生负面结果......)

他们来自哪里?显然我错过了一些错误,但我不知道是什么......?也许有些数据类型混乱了,但我找不到哪个和哪里。我试图改变一些事情,但这没有帮助。

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int compVal (const void *a, const void *b, void *direction) {
    int order = memcmp(a, b, sizeof(char)) * *(int *) direction;
    printf("number a: %d, number b: %d, order: %d\n", *(char *)a, *(char *)b, order);
    if (order > 0) {
        return 1;
    } else if (order < 0) {
        return -1;
    } else {
        return 0;
    }
}

int countOnes (char number) {
    int counter = 0;
    for (int i = 0; i < (8 * sizeof(char)); i++) {
        if (number & 1) {
            counter += 1;
        }
        number = number >> 1;
    }
    return counter;
}

int bitSequence (char number) {
    int bit = number & 1;
    number = number >> 1;
    int current = 1, max = 1;
    for (int i = 1; i < (8 * sizeof(char)); i++) {
        if ((number & 1) == bit) {
            current += 1;
            if (current > max) {
                max = current;
            }
        } else {
            current = 1;
        }
        bit = number & 1;
        number = number >> 1;
    }
    return max;
}

int compOnes (const void *a, const void *b, void *direction) {
    char achar = *(char *) a, bchar = *(char *) b;
    char acount = countOnes(achar);
    char bcount = countOnes(bchar);
    //return memcmp(&acount, &bcount, sizeof(char)) * *(int *) direction;
    printf("ones a: %d, ones b: %d\n", acount, bcount);
    return compVal(&acount, &bcount, &direction);
}

int compBitSeq (const void *a, const void *b, void *direction) {
    char achar = *(char *) a, bchar = *(char *) b;
    char aseq =  bitSequence(achar);
    char bseq = bitSequence(bchar);
    //return memcmp(&aseq, &bseq, sizeof(char)) * *(int *) direction;
    printf("sequence a: %d, sequence b: %d\n", aseq, bseq);
    return compVal(&aseq, &bseq, &direction);
}

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

    if (argc < 3) {
        printf("At least 2 values needed for sorting\n");
        return EXIT_FAILURE;
    }

    int direction = 1;

    qsort_r(&argv[1], argc - 1, sizeof(char *), compVal, &direction);           // 3, 7, 15, 32, 97

    //qsort_r(&argv[1], argc - 1, sizeof(char *), compOnes, &direction);        // 32, 3, (7, 97), 15

    //qsort_r(&argv[1], argc - 1, sizeof(char *), compBitSeq, &direction);      // (97, 15), (7, 32), 3

    //char test1 = countOnes(3), test2 = countOnes(7), test3 = countOnes(15), test4 = countOnes(32), test5 = countOnes(97);
    //printf("%d, %d, %d, %d, %d\n", test1, test2, test3, test4, test5);    // 2, 3, 4, 1, 3

    //test1 = bitSequence(3), test2 = bitSequence(7), test3 = bitSequence(15), test4 = bitSequence(32), test5 = bitSequence(97);
    //printf("%d, %d, %d, %d, %d\n", test1, test2, test3, test4, test5);    // 6, 5, 4, 5, 4

    for (int i = 1; i < argc; i++) {
        if (i == argc -1) {
            printf("%s\n", argv[i]);
        } else {
            printf("%s, ", argv[i]);
        }
    }

    return EXIT_SUCCESS;

}

1 个答案:

答案 0 :(得分:2)

您正在向int传递指向strcmp()的指针,该指针调用未定义的行为,因为strcmp()需要nul终止的字节序列不是整数。

尝试

memcmp(a, b, sizeof(int));

同样sizeof(char)始终为1,而CHAR_BIT不一定是8所以

for (int i = 1; i < 8 * sizeof(char); i++)

可以

for (int i = 1 ; i < CHAR_BIT ; i++)

代替。