Home > Enterprise >  how to sort a 2D char array
how to sort a 2D char array

Time:01-03

I am writing a program that opens a file (input.txt) and reads the lines into a 2D array so I can sort the lines by length.

These are my created sentences for testing (input.txt)

1. hello world
2. john Jones at Brook Mountains
3. Frozen Styx
4. altair
5. John Doe and Jane Doe
6. Cranium

my source.c

#define MAX_LINES 100
#define MAX_LEN 1000

int main(void) {

    char data[MAX_LINES][MAX_LEN];
    FILE* fread = fopen("C:\\Users\\EXAMPLE\\desktop\\input.txt", "r");

    if (fread == NULL) {
        printf("ERROR\n");
        return 1;
    }

    int line = 0;
    while (!feof(fread) && !ferror(fread)) {
        if (fgets(data[line], MAX_LEN, fread) != NULL) {
            line  ;
        }
    }

    fclose(fread);

    for (int i = 0; i < line; i  ) {
        printf("%s", data[i]);
    }

    return 0;
}

I managed to copy those lines and input them into a 2D array and am able to print it for testing, but I don't know how to go about sorting them by length. I found some close ideas but the first option didn't work for me. the second option is close but that sorts it's alphabetically.

  1. option 1
  2. option 2

CodePudding user response:

The first attempt doesn't work because you don't have an array of pointers, but an array of arrays. Also it's bad practice to allocate such huge arrays locally, since that may lead to stack overflow.

You could fix the code like this:

  • Change it to char* data [MAX_LINES];
  • Do fgets into a temporary buffer of MAX_LEN size.
  • Assign read strings to data with for example data[i] = strdup(tmpbuf);.
  • Now you can use the qsort and comparison callback function posted in your first attempt, because it assumes an array of character pointers and that's what you have now.
  • Remember to free() every data[i] when done using them.

CodePudding user response:

Here's a possible implementation using hardcoded data and featuring qsort; note that I also added lexicographic ordering in case two strings have the same length.

The user will have to make the necessary edits to implement import from file. I am just showing one possible implementation of the sorting function.

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

#define MAX_LINES 6

int compare_lengths(const void *a, const void *b)
{
    const char* str1 = *(const char* const*)a; // proper casting is crucial!
    const char* str2 = *(const char* const*)b;
    size_t len1 = strlen(str1);
    size_t len2 = strlen(str2);

    if (len1 < len2)
        return -1;
    if (len2 < len1)
        return  1;
    return strcmp(str2, str1); // same length -> sort lexicographically
}

int main(void) {

    char *data[MAX_LINES] = {0};

    data[0] = "hello world";
    data[1] = "john Jones at Brook Mountains";
    data[2] = "Frozen Styx";
    data[3] = "altair";
    data[4] = "John Doe and Jane Doe";
    data[5] = "Cranium";

    qsort(data, sizeof(data)/sizeof(char*), sizeof(char*), compare_lengths);

    for (int i=0; i<MAX_LINES;   i)
        printf("%s -> %ld\n", data[i], strlen(data[i]));
    return 0;
}

Code in action here.

  •  Tags:  
  • c
  • Related