I need a c language code to sort some strings and it should be case sensitive and for the same letter in upper- and lower-cases, the lower-case must come first
Here, if I got it right, you want something as I'd describe as follows:
A case insensitive sort, where under tie, tiebreaker condition "lowercase comes first" is to be used.
So it's like:
earlier_letter_in_the_alphabet < later_letter_in_the_alphabet
ignoring the case
lowercase < uppercase
shorter_word < wider_word
'\0'
as the lowest possible in comparisonsStep 2 to be taken only if 1 didn't distinguish anything. Step 3 will already be checked with 1. All these are to be done letter-by-letter, meaning that you should switch to 2 as soon as you get a tie between corresponding characters, not just when the whole strings are on tie.
Assuming that this was right, all we need to do now is to write a function that makes this comparison for us for any given two strings.
#include // for tolower and islower
int my_character_compare(const char a, const char b)
{
int my_result;
my_result = tolower(a) - tolower(b);
// unless it is zero, my_result is definitely the result here
// Note: if any one of them was 0, result will also properly favour that one
if (my_result == 0 && a != b)
// if (could not be distinguished with #1, but are different)
{
// means that they are case-insensitively same
// but different...
// means that one of them are lowercase, the other one is upper
if (islower(a))
return -1; // favour a
else
return 1; // favour b
}
// regardless if zero or not, my_result is definitely just the result
return my_result;
}
int my_string_compare(const char * a, const char * b)
{
int my_result;
my_result = my_character_compare(*a, *b);
// unless it is zero, my_result is definitely the result here
while (my_result == 0 && *a != 0)
// current characters deemed to be same
// if they are not both just 0 we will have to check the next ones
{
my_result = my_character_compare(*++a, *++b);
}
// whatever the my_result has been:
// whether it became != zero on the way and broke out of the loop
// or it is still zero, but we have also reached the end of the road/strings
return my_result;
}
A compare function, by convention/rule, should return a negative value for favouring the first parameter to be in front, negative value for favouring the second parameter, zero if it cannot distinguish them. Just an additional information which you likely already know by the way you make use of strcmp
.
And that's it! Replacing that strcmp
in your code with my_string_compare
here, also putting up these definitions we've made on top should provide a correct result. Indeed it provides the expected result for the example input in question.
One could shorten the definitions of course, I have made them long so that it will be easier to understand what's going on. For example, I could boil it all down to the following:
#include
int my_string_compare(const char * a, const char * b)
{
int my_result;
while (*a || *b)
{
if ((my_result = tolower(*a) - tolower(*b)))
return my_result;
if (*a != *b)
return (islower(*a)) ? -1 : 1;
a++;
b++;
}
return 0;
}
Does essentially the same with the other one, you may use whichever you like; or even better, write one.