Reputation: 75
I am trying to check if two arrays contain the same elements. Since I don't know if the input file is sorted correctly I want to use qsort()
to sort the array first and them compare it against the array cmpvalues
.
However I can't get qsort
to sort the array like the array cmpvalues
. The array where the values are stored should be sorted like the array cmpvalues
so that it's a lot easier to compare.
#include <stdio.h>
#define MAXCOLR 14
#define MAXLINE 100
#define MAXCHR 1024
#define _GNU_SOURCE
typedef struct {
char color[MAXCOLR];
int value;
} colorval_t;
int cmpfunc(const void *a, const void *b) {
int aa, bb;
aa = *(int *)a;
bb = *(int *)b;
return (aa - bb);
}
int main(int argc, char **argv) {
size_t n;
int cmpvalues[] = {
65,
2,
3,
4,
5,
6,
7,
8,
9,
10,
74,
81,
75,
65,
2,
3,
4,
5,
6,
7,
8,
9,
10,
74,
81,
75
};
size_t ndx = 0;
char buf[MAXCHR];
colorval_t arr[MAXLINE] = {{ .color = "" }};
FILE *fp = argc > 1 ? fopen(argv[1], "r") : stdin;
if (!fp) {
perror("file open failed");
return 1;
}
while (ndx < MAXLINE && fgets(buf, MAXCHR, fp)) {
char c;
if (sscanf(buf, "%13s %d", arr[ndx].color, &arr[ndx].value) == 2)
ndx++;
else if (sscanf(buf, "%13s %c", arr[ndx].color, &c) == 2) {
arr[ndx].value = c;
ndx++;
}
}
if (fp != stdin)
fclose(fp);
for (size_t i = 0; i < ndx; i++)
printf("arr[%2zu] : %s %d\n", i, arr[i].color, arr[i].value);
//sorts the array
qsort(arr, 26, sizeof(arr[26]), cmpfunc);
for (n = 0 ; n < 26; n++) {
printf("%d ", arr[n].value);
}
//checks if arrays have the same element
int j;
for (j = 0; j < 26; j++) {
if (arr[j].value != cmpvalues[j]) {
printf("wrong");
break;
}
}
return 0;
}
input:
RED A
RED 2
RED 3
RED 4
RED 5
RED 6
RED 7
RED 8
RED 9
RED 10
RED J
RED Q
RED K
BLACK 10
BLACK J
BLACK Q
BLACK K
BLACK A
BLACK 2
BLACK 3
BLACK 4
BLACK 5
BLACK 6
BLACK 7
BLACK 8
BLACK 9
Upvotes: 2
Views: 893
Reputation: 409216
Your comparison function is wrong.
The qsort
function passes pointers to the elements in the array you sort, so if you have an array of colorval_t
then the arguments are of type colorval_t *
.
Since you treat the pointers are int *
you have a mismatch, and that will lead to undefined behavior.
That means your comparison function should look something like
int cmpfunc (const void * a, const void * b) {
colorval_t *first = (colorval_t *) a;
colorval_t *second = (colorval_t *) b;
return first->value - second->value;
}
Upvotes: 1