Tandura
Tandura

Reputation: 908

Comparing strings with qsort

I want to read n strings from a file and sort them alphabetically Here is my version of code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    char **citireMatrice(int *n)
    {
        char c;
        char sep[] = " ,./;:'[]{}|`~!@#$%^&*()\n";
        char **x=NULL;
        char **aloca=NULL;
        char *valoca=NULL;
        int citireCaracterNormal=0;
        int lungime=0;
        FILE *f = fopen("date.in","r");

    x = (char **)malloc(1*sizeof(char *));
    *n = 1;
    *(x+(*n)-1) = NULL;
    while((c = fgetc(f))!=EOF)
    {
        if(strchr(sep,c))
        {
            if(citireCaracterNormal)
            {
                lungime++;  //adaug '\0' la sfarsit-ul cuvantului
                valoca = (char *)realloc(*(x+(*n)-1),lungime*sizeof(char));
                if(valoca == NULL)
                {
                    printf("Eroare de alocare a memoriei!");
                    exit(1);
                }
                *(x+(*n)-1) = valoca;
                *(*(x + (*n)-1) + lungime -1) = '\0';
                lungime = 0;

                (*n)++;
                aloca = (char **)realloc(x,(*n)*sizeof(char*));
                if(aloca == NULL)
                {
                    printf("Eroare de alocare a memoriei!");
                    exit(1);
                }
                x = aloca;
                *(x+(*n)-1) = NULL;

                citireCaracterNormal = 0;
            }
        }
        else
        {
            lungime++;
            valoca = (char *)realloc(*(x+(*n)-1),lungime*sizeof(char));
            if(valoca == NULL)
            {
                printf("Eroare de alocare a memoriei!");
                exit(1);
            }
            *(x+(*n)-1) = valoca;
            *(*(x + (*n)-1) + lungime - 1) = c;

            citireCaracterNormal = 1;
        }
    }
    (*n)--;
    fclose(f);
    return x;
}

void afisare(char **x,int n)
{
    int i;
    for(i=0;i<n;i++)
        printf("%s\n",*(x+i));
}

int predicat(const void *a,const void *b)
{
    return -strcmp((char *)a,(char *)b);
}

int main()
{
    int n;
    char **x = citireMatrice(&n);
    afisare(x,n);
    qsort(x,n,sizeof(char *),predicat);
    printf("\n\nDupa sortare:\n\n");
    afisare(x,n);
    return 0;
}

the problem is that it does not sort them right. what is wrong with predicat function? the paramethers a and b are not the corect adresses form the x array.

Upvotes: 0

Views: 163

Answers (2)

abelenky
abelenky

Reputation: 64682

The function passed to qsort (predicat here), takes a pointer to each element to be compared.

Since the things you want to sort are char*, your function will be passed char**.

I believe you should rewrite this way:

int predicat(const void* a, const void* b)
{
    char* pStrA = *(char**)a;
    char* pStrB = *(char**)b;

    printf("Comparing %s to %s\n", pStrA, pStrB); // To verify you have the right strings.

    return -strcmp(pStrA, pStrB);
}

Upvotes: 2

R Sahu
R Sahu

Reputation: 206567

The arguments to predicat are not char const*. They are char const**. You need to use:

int predicat(const void *a,const void *b)
{   
    return -strcmp(*(char const**)a, *(char const**)b);
}

Also, by using

    return -strcmp(*(char const**)a, *(char const**)b);

you will be sorting them in reverse order. I don't know whether you meant to do that. If not, use

    return strcmp(*(char const**)a, *(char const**)b);

Upvotes: 0

Related Questions