【问题标题】:Read lines from a file and create alphabetically sorted array从文件中读取行并创建按字母排序的数组
【发布时间】:2015-03-20 05:32:12
【问题描述】:

我正在学习 C,我想做这个特定的任务。我知道有许多类似的问题和答案,但仍然......我会尝试更具体。可以说,我有一个包含以下几行的文件:

program01
programs
aprogram
1program
prog
5program

我现在想要一个数组:

1program
5program
aprogram
prog
program01
programs

所以字符串中只有拉丁小写字母和数字,没有空格。我知道如何执行一些单独的步骤,但想了解和感受整个(和正确的)概念,可以这么说。在首先从文件中读取时,它可能会即时做出一些排序决定?对于我的特殊情况,手动排序是首选,只是为了更好的学习和可能的优化。可以说,一行的最大长度是 256,最大行数是 256。提前致谢。

【问题讨论】:

  • 我知道如何执行一些单独的步骤,好的,请展示您所知道的以及您在哪里卡住了,我很乐意提供帮助,因为我确信其他 SO用户会。
  • 1) 阅读。 2) 排序。问题出在哪里?
  • 我认为你应该从类似的问题之一开始,并根据自己的需要进行调整,毕竟它们基本上都是相同的问题,但遇到的问题不同。
  • 1) char buffer[256][256 + 2] 2) 调用 fgets() 最多 256 次。 3)qsort()。 4) 打印线条。
  • @iharob (和其他) 很高兴你很乐意提供帮助,所以我知道 char* 只是一个字节数组,我可以像 int 一样比较每个字符。比较两个字符串很容易。但是由于缺乏 C 语法知识,尤其是指针运算,我发现一些排序示例很难理解。

标签: c arrays sorting


【解决方案1】:

检查以下代码:

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

int main(void) {
    char a[256][256];
    int i=0,j=0,k=0,n;

    while(i<256 && fgets(a[i],256,stdin) != NULL)
    {
        n = strlen(a[i]);
        if(n >0 && a[i][n-1] == '\n')
        a[i][n -1] = '\0';
        i++;
    }

    for(j=0;j<i;j++)
    {
        char max[256];
        strcpy(max,a[j]);
        for(k=j+1;k<i;k++)
        {
            if(strcmp(a[k],max) < 0)
            {
                char tmp[256];
                strcpy(tmp,a[k]);
                strcpy(a[k],max);
                strcpy(max,tmp);
            }
        }
        strcpy(a[j],max);
    }

    for(j=0;j<i;j++)
    {
        printf("%s\n",a[j]);
    }
    return 0;
}

【讨论】:

  • 我在here 发表的评论大多也适用于这里。如果一行适合if(strlen(a[i]) &lt; 255),IMO,最好抱怨而不是继续。否则,分割线将被分类到可能 2 个位置。建议确保i 不超过 255/6。
  • @chux 感谢您的意见
【解决方案2】:
The following cleanly compiles
however, I have not tested it

you might want to modify it to get the file name from 
the command line

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

#define MAX_ROWS (256)
#define MAX_COLUMNS (256)
#define FILE_NAME "myInputFile"

// prototypes
void bubbleSortWordsArray( int wordCount );
void printWordsArray( int wordCount );

static char words[MAX_ROWS][MAX_COLUMNS] = {{'\0','\0'}};

int main(void)
{
    FILE *fp = NULL;

    if( NULL == (fp = fopen( FILE_NAME, "r") ) )
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    // read each line from file into entry in words array
    int i = 0;
    while( fgets(words[i], MAX_COLUMNS, fp ) )
    {
        // remove trailing newline from string
        words[i][strlen(words[i])-1] = '\0';
        i++;
    }

     // 'i' contains number of valid entries in words[][]
    // sort the array of strings
    bubbleSortWordsArray(i);

    printWordsArray(i);

    return(0);
} // end function: main


void bubbleSortWordsArray( int wordCount )
{
    int c;  // outer index through rows
    int d;  // inner index through rows
    char swap[MAX_COLUMNS] = {'\0'};

    for (c = 0 ; c < ( wordCount - 1 ); c++)
    {
        for (d = 0 ; d <  (wordCount - c - 1); d++)
        {
            if(  0 > strcmp( words[d], words[d+1] ) )
            { // then words need to be swapped
                strcpy( swap, words[d]  );
                strcpy( words[d], words[d+1]);
                strcpy( words[d+1], swap );
            } // end if compare/swap
        } // end for
    } // end for each row
} // end function: bubbleSortWordsArray


void printWordsArray( int wordCount )
{
    int i; // loop index

    printf( "\n" ); // start on new output line
    for( i=0; i<wordCount; i++ )
    {
        printf( "%s\n", words[i] );
    }
} // end function: printWordsArray

【讨论】:

  • 小想法:1) 最大行 length 为 256,这通常需要为 '\n''\0' 提供额外的缓冲区空间,2) words[i][strlen(words[i])-1] 是一个问题在极少数情况下,当行以嵌入的'\0' 3) 开头时,代码会自行排序而不是调用qsort()。 4) 不需要初始化words - 但也不错。
  • @chux 也适用于例如如果 buf 大小是 5 并且输入是 1234 那么 a[i][strlen(a[i]) -1] = '\0' 不应该正确完成,所以我在我的代码中检查相同跨度>
【解决方案3】:

制作一个二维字符数组 尝试使用 fscanf 函数读取它(对不起,我不记得语法)。 fscan 将读取您的整行直到 '\n' 但不应该有空格 并将每个字符串存储在一行中。 然后通过比较每个字符串的第一个索引对其进行排序

【讨论】:

  • 最好使用fgets()
  • 使用 fgets 可能是一个问题,因为它会选择 '\n' 并且可以跳过一些进一步的字符串。所以你必须刷新'\n'。
  • 这不是问题,这是一项任务。至于“可以跳过更多的字符串”,您更愿意破坏您的缓冲区吗?
  • "fscan 将读取你的整行直到 '\n'" --> 不。没有单一的fscanf() 调用会“读取你的整行直到'\n”。如果行以'\n' 开头,即使fscanf("%[^n]") 也会失败。使用fgets()
  • 文件 *fp;字符 [5][25];诠释我=0; fp=fopen("abc.txt","r"); while(!feof(fp)){ fscanf(fp,"%s",a[i]); printf("%s\n",a[i]);我++; } 它将读取整行但不附加 '\n' 并且 fgets 可以附加它 '\n'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-28
  • 1970-01-01
  • 2021-05-21
  • 2016-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多