Search code examples
cstringsortingc-stringsalphabetical

C program sort strings in alphabetical order


I'm new to C programming and I'm trying to write a code which sorts words in alphabetical order. I considered capital letters and small letters different. My rules for sorting is first to consider alphabetical order, and then capital letters have priority, and words with fewer characters has priority. For all words we consider only first and second letters characters, if they are similar we go to next word.
Finally when 0 is entered, the program should finish.
Here is an example of what should it do:
input : alireza Mohammad Arash anahita sarah Milad john Alireza Maryam 0
output : Alireza alireza anahita Arash john Maryan Milad Mohammad sarah

#include<stdio.h>
#include<string.h>
int main() {
    int i=0, j=0, count;
    char str[25][25], temp[25];
    while (1) {
        gets(str[i]);
        if(str[i][0]=='0')
            break;
        i++;
        j++;
    }
    count=i;
    for(i=0; i<=count; i++)
        for(j=i+1; j<=count; j++) {
            if(strcmp(str[i], str[j]) > 0) {
                strcpy(temp, str[i]);
                strcpy(str[i], str[j]);
                strcpy(str[j], temp);
            }
         }
    for(i=0; i<count; i++)
        printf("%s ", str[i]);
    return 0;
}

but my code only sort words by comparing their ASCII code which cause all capital come first like
input : aa bb AA we WE 0
my output : AA WE aa bb we
but it should be:
output : AA aa bb WE we
I was thinking if I could do something like creating new ASCII code for chars but it also seem impossible. How could sort strings like this?


Solution

  • You need a "new" strcmp() tailored to your specific needs:

    enum /*untagged*/ { AbeforeB = -1, AequalsB = 0, AafterB = 1 };
    
    int tailored_strcmp(const char *a, const char *b) {
        static char baseorder[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
        //if a or b is the empty string
        if (*a == 0) return AbeforeB;
        if (*b == 0) return AafterB;
        int lena = strlen(a);
        int lenb = strlen(b);
        char *pa = strchr(baseorder, *a);
        char *pb = strchr(baseorder, *b);
        if (pa == NULL) return lena < lenb ? AbeforeB : AafterB;
        if (pb == NULL) return lena < lenb ? AbeforeB : AafterB;
        if (pa == pb) {
            //need to check second letter
            if (a[1] == 0) return AbeforeB;
            if (b[1] == 0) return AafterB;
            char *ppa = strchr(baseorder, a[1]);
            char *ppb = strchr(baseorder, b[1]);
            if (ppa == NULL) return lena < lenb ? AbeforeB : AafterB;
            if (ppb == NULL) return lena < lenb ? AbeforeB : AafterB;
            if (ppa == ppb) return lena < lenb ? AbeforeB : AafterB;
            return ppa < ppb ? AbeforeB : AafterB;
        }
        return pa < pb ? AbeforeB : AafterB;
    }
    

    See version running at ideone, or version with improved adherence to requirements or version checking 1-length strings