排序字符串无法正常工作

时间:2011-10-29 17:56:38

标签: c sorting

我有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]关闭终端... 当我使用像kuća这样的非ascii字符用于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 个答案:

答案 0 :(得分:2)

你总是将行[j]与行[i]进行比较,但你应该将它与行[min]进行比较。

答案 1 :(得分:2)

1.-您必须在malloc之后将行初始化为0,以便strlen正常工作。 2.-将线[j]与线[min]进行比较 3.-不要忘记免费线路

答案 2 :(得分:1)

如果你不是在学习如何排序和获取输入,那么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]);
 }

你用这种方式做得更清楚。

答案 3 :(得分:0)

轻微的挑剔:

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)

,否则“apple”和“apples”将相等(因为只会比较前五个字符)。但是“正常”形式:

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

完全符合您的要求。