1

I have rjecnik.txt file that looks like this

mate sime, jure
stipica gujo, prvi
ante mirkec
goran maja, majica
avion kuca, brod, seoce
amerika, neka, zemlja, krcma
brodarica, zgrada, zagreb
zagreb split
zadar rijeka
andaluzija azija

I need to order lines alphabetically (not words) and my program produces this result which is not correct:

andaluzija azijamate sime, jure
amerika, neka, zemlja, krcma
brodarica, zgrada, zagreb
ante mirkec
avion kuca, brod, seoce
goran maja, majica
stipica gujo, prvi
zadar rijeka
zagreb split

Press [Enter] to close the terminal ... When I use non ascii character like kuća for kuca or krčma for krcma it produces this result (all wrong)

andaluzija azijamate sime, jure
amerika, neka, zemlja, krŔma
brodarica, zgrada, zagreb
ante mirkec
avion kuŠa, brod, seoce
goran maja, majica
stipica gujo, prvi
zadar rijeka
zagreb split

Press [Enter] to close the terminal ... This is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    int ch, nl = 1, min, lenght1, lenght2, lenght;//ch will hold characters, min is for selection sort, lenght holds value of strlen for determine wthat line is longer
    FILE * fp;// FILE pointer
    char * lines[1000];//that will dynamically hold strings for lines
    char * temp;//for lines swaping
    if((fp = fopen("C:\\Users\\don\\Documents\\NetBeansProjects\\proba2\\dist\\Debug\\MinGW-Windows\\rjecnik.txt", "r")) == NULL)//I had to temporarily put full path to rjecnik.txt
    {
        printf("Can't open file...");
        exit(1);
    }
    while((ch = getc(fp)) != EOF)//count lines
    {
        if(ch == '\n')
            nl++;
    }
    int i, j;
    for (i = 0; i < nl; i++)
        lines[i] = malloc(1000);//create array of string size value of nl
    fseek(fp, 0L, SEEK_SET);//go to start of file
    i = 0;
    j = 0;
    while((ch = getc(fp)) != EOF)//fill arrays of string
    {
        lines[i][j] = ch;
        j++;
        if(ch == '\n')
        {
           j = 0;
           i++;
        }
    }
    for(i = 0; i < nl - 1; i++)//selection sort doesn't work properly
    {
        min = i;//min is i
        for(j = i + 1; j < nl; j++)//for number of lines(nl) times
        {
            lenght1 = strlen(lines[i]);//find what string is longer and lenght is smaller one
            lenght2 = strlen(lines[j]);
            if(lenght1 < lenght2)
                lenght = lenght1;
            else
                lenght = lenght2;
            if(strncmp(lines[i], lines[j], lenght) > 0 )//compare two strings
                 min = j;//if second string is alphabetically smaller min is j
        }
        temp = lines[i];// swapping
        lines[i] = lines[min];
        lines[min] = temp;
    }
    for(i = 0; i < nl; i++ )//printing to console
    {
        lenght1 = strlen(lines[i]);
        for(j = 0; j < lenght1; j++ )
        {
            putchar(lines[i][j]);
        }
    }
    return 0;
}

Now program crashes at the end when I add this code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    int ch, nl = 1, min, lenght1, lenght2, lenght;//ch will hold characters, min is for selection sort, lenght holds value of strlen for determine wthat line is longer
    FILE * fp;// FILE pointer
    char * lines[1000];//that will dynamically hold strings for lines
    char * temp;//for lines swaping
    if((fp = fopen("C:\\Users\\don\\Documents\\NetBeansProjects\\proba2\\dist\\Debug\\MinGW-Windows\\rjecnik.txt", "r")) == NULL)//I had to temporarily put full path to rjecnik.txt
    {
        printf("Can't open file...");
        exit(1);
    }
    while((ch = getc(fp)) != EOF)//count lines
    {
        if(ch == '\n')
            nl++;
    }
    int i, j;
    for (i = 0; i < nl; i++)
        lines[i] = malloc(1000);//create array of string size value of nl
    fseek(fp, 0L, SEEK_SET);//go to start of file
    i = 0;
    j = 0;
    while((ch = getc(fp)) != EOF)//fill arrays of string
    {
        lines[i][j] = ch;
        j++;
        if(ch == '\n')
        {
           j = 0;
           i++;
        }
    }
    for(i = 0; i < nl - 1; i++)//selection sort doesn't work properly
    {
        min = i;//min is i
        for(j = i + 1; j < nl; j++)//for number of lines(nl) times
        {
            lenght1 = strlen(lines[i]);//find what string is longer and lenght is smaller one
            lenght2 = strlen(lines[j]);
            if(lenght1 < lenght2)
                lenght = lenght1;
            else
                lenght = lenght2;
            if(strncmp(lines[min], lines[j], lenght ) > 0 )//compare two strings
                 min = j;//if second string is alphabetically smaller min is j
        }
        temp = lines[i];// swapping
        lines[i] = lines[min];
        lines[min] = temp;
    }
    for(i = 0; i < nl; i++ )//printing to console
    {
        lenght1 = strlen(lines[i]);
        for(j = 0; j < lenght1; j++ )
        {
            putchar(lines[i][j]);
        }
    }
   for (i = 0; i < 100; i++)//Program crashes here
        free(lines[i]);

    return 0;
}

4 Answers 4

2

1.- You must initialize lines to 0 after malloc so strlen works properly. 2.- Compare lines[j] with lines[min] 3.- Don't forget free lines

Sign up to request clarification or add additional context in comments.

3 Comments

Wait, when I want to free lines at the end of the program with for (i = 0; i < 100; i++) free(lines[i]); program crashes
You're only allocating for n1 lines, so you should only free those.
sorry I now I made mistake thinking about somting else
2

You're always comparing lines[j] to lines[i], but you should be comparing it to lines[min].

Comments

1

If this isn't you learning about how to sort and get input, c provides qsort() and fgets(), so you could

 int strsort(const void *a, const void *b)
 {
      char *const*astr=a, *const*bstr=b;
      return strcmp(*astr, *bstr);
 }

 main()
 {
     FILE*f = fopen(...);
     char (*arr)[1000] = malloc(1000*1000);
     int x;
     for(x=0;x<1000 && fgets(1000, arr[x], f);x++)
         arr[x][strlen(arr[x])-2] = '\0'; //strip newlines
     qsort(arr, x, 1, strsort);
     int i;
     for(i=0; i<x; i++)
          printf("%s\n", arr[x]);
 }

It's much clearer what you're doing this way.

Comments

0

Minor nitpick:

lenght1 = strlen(lines[i]);
            lenght2 = strlen(lines[j]);
            if(lenght1 < lenght2)
                lenght = lenght1;
            else
                lenght = lenght2;
            if(strncmp(lines[i], lines[j], lenght) > 0 )
 ... ;

You don't need this: strcmp() stops when either of the strings terminates, whichever comes first. In your case, you need to compare one more character (the NUL), like

strncmp( lines[i], lines[j], lenght+1)

, otherwise "apple" and "apples" would compare equal (because only the first five characters would be compared). But the "normal" form:

strcmp(lines[i], lines[j])

does exactly what you want.

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.