Сортировка строк не работает должным образом - PullRequest
1 голос
/ 29 октября 2011

У меня есть файл rjecnik.txt, который выглядит следующим образом

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

Мне нужно упорядочить строки в алфавитном порядке (не слова), и моя программа выдает неправильный результат:

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

Нажмите [Enter], чтобы закрыть терминал ... Когда я использую не ascii символ, такой как kuća для kuca или krčma для krcma, это дает такой результат (все неправильно)

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

Нажмите [Enter], чтобы закрытьтерминал ... Это мой код:

#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;
}

Теперь программа завершается сбоем в конце, когда я добавляю этот код:

#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 ]

2 голосов
/ 29 октября 2011

1.- Вы должны инициализировать строки в 0 после malloc, чтобы strlen работал правильно.2.- Сравните строки [j] со строками [мин] 3.- Не забудьте свободные строки

2 голосов
/ 29 октября 2011

Вы всегда сравниваете строки [j] со строками [i], но вы должны сравнивать их со строками [мин].

1 голос
/ 29 октября 2011

Если вы не изучаете, как сортировать и получать ввод, c предоставляет qsort() и fgets(), чтобы вы могли

 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]);
 }

Это намного яснее, что вы делаете таким образом.

0 голосов
/ 29 октября 2011

Незначительный придира:

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

Вам это не нужно: strcmp () останавливается, когда завершается любая из строк, в зависимости от того, что произойдет раньше.В вашем случае вам нужно сравнить еще один символ (NUL), например

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

, иначе «яблоко» и «яблоки» будут сравниваться одинаково (поскольку сравниваются только первые пять символов).Но «нормальная» форма:

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

делает именно то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...