Reputation: 25
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 !
Upvotes: 1
Views: 184
Reputation: 144715
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;
}
Upvotes: 1