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.
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 ofMAX_LEN
size. - Assign read strings to
data
with for exampledata[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()
everydata[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.