Given a two dimensional array decalred below:
char * Arr[4] =
{
{"124 -346 DATA...."},
{"39479 -32 MOREDATA...."},
{"12 -1 DATA2...."},
{"100 -45 DATA4...."}
};
i’m trying to use qsort() to sort this function according to the SECOND field, meaning the strings would be ordered according to the lowest second value(-1,-32,-45,-346). I know how to make this function if each value were only one digit, but the digits in the program could be arbitrarily long. here is what i have but the program crashes, if there is a more efficient way to sort this data i would love to here it(i know my method can’t be very efficient).
Sort function(which qsort() calls):
inline void GetStr(char *ix, char* Result) //call to get second number in function
{
char *spacing; //iterator to traverse
spacing = ix; //iterator = pos of ix
int LEN = 0; //length and offset
int Offset = 0;
while(*spacing != ' ') //while not at end of first num
{
Offset++; //offset is more
spacing++;
}
spacing++; //go one ahead of the space
Offset++;
while(*spacing != ' ') //while not end of second number
{
spacing++;
Offset++;
LEN++; //length of number
}
strncpy(Result, ix + (Offset - LEN),LEN);
}
int sort(const void* a, const void* b)
{
char *ia = *(char**)a;
char *ib = *(char**)b;
char * Str;
char * Str2;
GetStr(ia, Str); //getting some strange errors....... program just crashes
GetStr(ib, Str2);
printf("Str: %s Str2: %s", Str, Str2);
int n1 = atoi(Str);
int n2 = atoi(Str2);
return (n1 > n2);
}
I believe you have at least one problem here:
If you look at the documentation for
strncpy, you will see that it does not automatically null-terminate the copied string if you hit the character limit. Therefore yourResultstrings are not null-terminated.Try changing to this:
Of course, you still need to provide memory for the Result string. Currently you are passing an uninitialized pointer into
GetStr():Since these are fairly small integers you can use statically allocated storage like this:
Finally, there are some issues with your
sort()function. If you look at the qsort() documentaton, you can see that the return value should be “an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second”. The easiest way to achieve this is with the logicn1 - n2instead of then1 < n2.I also thought you’re sort arguments of type
char **were odd as well, but upon further reflection I realize they are correct. From the qsort docs: “two arguments that point to the objects being compared”. So indeed they will be pointers to C strings orchar **.So here is the final version: