1

I have problem to sort an array of string by length loaded from txt file.

So I read from the file line by line and put the strings into an array, after that I sort that array by the length of the string, but I get a strange output of the array stream.

The problem is that the program is sorting an array of strings, but one of the strings is pasted on top of another.

Example:

The data in the file I'm reading from:

X&Y
X|Y
!X
(X|Y)|Z
(X&Y)|Z
(X&Y)&Z
(X&Y)|Z&(A|B
((X|Y)|Z)&((A|B)|(C&D))
(X&Y)|(Z&(A|B))
(A|B)&(!C)
A|(B&(C&(D|E)))
((X|Y)|(Z&(A|B)))|((C&D)&(D|E))
(A|B)|(C&D)&(D|E)
!A&(B|C)
(A|B)|(C|D)&(D

Content of the array after sorting in ascending order:

!X
X|Y
X&Y
(X|Y)|Z
(X&Y)|Z
(X&Y)&Z
!A&(B|C)
(A|B)&(!C)
(X&Y)|Z&(A|B
(A|B)|(C|D)&(DA|(B&(C&(D|E))) //Here' is problem ! (A|B)|(C|D)&(D and A|(B&(C&(D|E))) are concatenated?
(X&Y)|(Z&(A|B))
(A|B)|(C&D)&(D|E)
((X|Y)|Z)&((A|B)|(C&D))
((X|Y)|(Z&(A|B)))|((C&D)&(D|E))




Here is the code:

//Sort function
void sort(char str[][MAXLEN], int number_of_elements) {
    int d, j;
    char temp[100];
    for (d = 0; d < number_of_elements - 1; d++) {
        for (j = 0; j < number_of_elements - d - 1; j++) {
            if (strlen(str[j]) < strlen(str[j + 1])) {
                strcpy(temp, str[j]);
                strcpy(str[j], str[j + 1]);
                strcpy(str[j + 1], temp);
            }
        }
    }
}

int main() {
    FILE *dat;
    int number_of_elements;
    char str[MAX][MAXLEN];
    int i = 0;
    dat = fopen("ulaz.txt", "r");
    if (dat == NULL) {
        printf("Error");
    }
    while (!feof(dat) && !ferror(dat)) {
        if (fgets(str[i], 100, dat) != NULL)
            i++;
    }

    number_of_elements = i;
    fclose(dat);
    
    sort(str, number_of_elements);
    
    for (int d = 0; d < i; d++) {
        printf("%s", str[d]);
    }
    return 0;
}

Thanks in advance !

7
  • Works exactly as I would expect, after changing the comparison from a less-than to a greater-than. replit.com/@robertwharvey/LowQuarterlyMemorypool#main.c Commented Nov 12, 2022 at 13:17
  • You don't have concatenate strings like me? Commented Nov 12, 2022 at 13:21
  • @user3121023 how to fix that? I still have the same problem... Commented Nov 12, 2022 at 13:26
  • Check your data file. The one in the example I provided has a trailing newline after the last line. Commented Nov 12, 2022 at 13:27
  • To fix it, simply add a newline after the last line, if it is not there. Commented Nov 12, 2022 at 13:28

1 Answer 1

1

Your observations is consistent with the last line of the source file having no trailing newline: (A|B)|(C|D)&(D

You can correct the problem by stripping the newline after fgets() and always appending one in the output phase.

Also make sure that the temporary array used for swapping the strings is long enough: instead of 100 bytes, it should have a length of MAXLEN. Also stop reading from the file when i reaches MAX.

Here is a modified version:

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

#define MAXLEN  200
#define MAX     100

//Sort function by decreasing string lengths
void sort(char str[][MAXLEN], int number_of_elements) {
    int d, j;
    for (d = 0; d < number_of_elements - 1; d++) {
        for (j = 0; j < number_of_elements - d - 1; j++) {
            if (strlen(str[j]) < strlen(str[j + 1])) {
                char temp[MAXLEN];
                strcpy(temp, str[j]);
                strcpy(str[j], str[j + 1]);
                strcpy(str[j + 1], temp);
            }
        }
    }
}

int main() {
    int number_of_elements;
    char str[MAX][MAXLEN];
    int i;
    FILE *dat = fopen("ulaz.txt", "r");
    if (dat == NULL) {
        fprintf(stderr, "Cannot open %s: %s\n", "ulaz.txt", strerror(errno));
        return 1;
    }
    for (i = 0; i < MAX && fgets(str[i], MAXLEN, dat) != NULL; i++) {
        /* strip the trailing newline if any */
        str[i][strcspn(str[i], "\n")] = '\0';
    }

    number_of_elements = i;
    fclose(dat);
    
    sort(str, number_of_elements);
    
    for (int d = 0; d < number_of_elements; d++) {
        printf("%s\n", str[d]);
    }
    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.