作为一个家庭作业,我编写了这个应该使用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;
}
答案 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++)
代替。