Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qsort array of strings in alphabetical order

Tags:

arrays

c

qsort

Im trying to sort a array of strings I read from a file in alphabetical order using the qsort function. This is my code:

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

#define MAXCHAR 256


int main(int argc, char **argv){
    char tempList[MAXCHAR][MAXCHAR];
    char reader[MAXCHAR];
    FILE* fp;
    int i;
    char *n;
    int index = 0;
    if(argc != 2){
        printf("too few arguments\n");
        exit(-1);
    }

    fp=fopen(argv[1], "r");
    if(fp == NULL){
        printf("failed to open file\n");
        exit(-1);
    }
    while(!feof(fp)){
        fgets(reader, MAXCHAR, fp);
        n = strchr(reader, '\n');
        if(n != NULL){
            *n = '\0';
        }
        strcpy(tempList[index], reader);
        index++;
    }
    index--;
    for(i=0; i<index; i++){
        printf("%s\n", tempList[i]);

    }
    qsort(tempList, index, sizeof(char *), strcmp);

    for(i=0; i<index; i++){
        printf("%s\n", tempList[i]);
    }
}

When I run the program, the list doesn't get sorted at all. I also tried methods posted on this website that asks a similar question and they all give me segmentation faults. Is there something wrong with the code?

Here is part of the content of the txt file. It is a list of 40 names:

Liam
Alexander
Mia
Noah
Emma
William
Charlotte
Charlotte
Mason
William
Ethan
Ethan
Liam
Alexander
Liam
Sophia
Emily
Mason
Alexander
like image 266
NewbieProgrammer Avatar asked Jan 20 '26 16:01

NewbieProgrammer


2 Answers

You have a bona fide array of arrays; not an array of char*. Arrays aren't pointers. qsort expects the stride of the elements in the sequence being sorted. As your sequence is declared as:

char tempList[MAXCHAR][MAXCHAR];

the proper element size is the size of the inferior element size. In this case you have an array of size MAXCHAR of array of char of size MAXCHAR (an array of arrays).

Thus this is wrong:

qsort(tempList, index, sizeof(char *), strcmp);
// wrong size ==============^^^^

the size of each element should be:

qsort(tempList, index, sizeof tempList[0], strcmp);
// correct size ==============^^^^

The other issues in your program will eventually grief you and are covered in general comments below your question, but this is the fundamental problem preventing your sorting from working correctly. A retooled version of your program appears below, addressing most of those concerns:

Updated Source

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

#define MAXCHAR 256

/* properly declared for compatibility with qsort */
static int cmp_str(const void *lhs, const void *rhs)
{
    return strcmp(lhs, rhs);
}

/* main entrypoint */
int main(int argc, char **argv)
{
    char tempList[MAXCHAR][MAXCHAR];
    FILE* fp;
    size_t i, index = 0;

    if(argc != 2)
    {
        printf("too few arguments\n");
        return EXIT_FAILURE;
    }

    fp=fopen(argv[1], "r");
    if(fp == NULL)
    {
        perror(argv[1]);
        return EXIT_FAILURE;
    }

    while(index < MAXCHAR && fgets(tempList[index], sizeof(*tempList), fp) != NULL)
    {
        char *n = strchr(tempList[index], '\n');
        if(n != NULL)
            *n = 0;
        if (*(tempList[index])) /* don't insert blank lines */
            ++index;
    }

    for(i=0; i<index; i++)
        printf("%s\n", tempList[i]);
    fputc('\n', stdout);


    qsort(tempList, index, sizeof tempList[0], cmp_str);

    for(i=0; i<index; i++)
        printf("%s\n", tempList[i]);

    return EXIT_SUCCESS;
}

Untested, but it should be pretty close.

Best of luck.

like image 102
WhozCraig Avatar answered Jan 23 '26 05:01

WhozCraig


Your size value in qsort(tempList, index, sizeof(char *), strcmp); is wrong. It should be qsort(tempList, index, sizeof(*tempList), strcmp);.

like image 26
Robert Jacobs Avatar answered Jan 23 '26 05:01

Robert Jacobs