【问题标题】:C Program: Sort a text file with records alphabetical orderC程序:按字母顺序对文本文件进行排序
【发布时间】:2015-10-25 22:22:21
【问题描述】:

我是文件处理的新手,希望帮助我阅读一个文本文件,其中包含人们的名字和姓氏、地址、城市、州、邮政编码和电话号码,所有这些都用“\t”分隔,并且将其复制到另一个文件中。读取的文件可以保存任意数量的记录。

我希望能够仅按城市字母顺序对这些记录进行排序。我是文件处理的新手,所以我不确定如何在读取文件后进行处理,以及如何在比较功能中进行处理。另外,在我的代码中,我注释掉了一些代码,用于显示每个文件包含的内容。我的问题是当它没有被注释掉并且是程序的一部分时,文本文件不会复制到目标文件。这是为什么呢?

提前感谢您的帮助!我的代码在这里:

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

typedef struct contacts {
    char fname[1000];
    char lname[1000];
    char address[1000];
    char city[1000];
    char state[1000];
    char zip[1000];
    char num[1000];
}ContactType;

#define MaxContacts 1000
ContactType contacts[MaxContacts];
int ncontacts = 0;// update to number of records stored in contacts[] 

int CompareCity(void *pa, void *pb);

int main()
{
    char ch, copy, show, source_file[1000], target_file[1000];
    FILE *source, *target;

    printf("Enter name of file to copy\n");
    gets(source_file);

    source = fopen(source_file, "r");

    if (source == NULL)
    {
        printf("Could not open file.\n");
        exit(EXIT_FAILURE);
    }

    printf("Enter name of target file\n");
    gets(target_file);

    target = fopen(target_file, "w");

    if (target == NULL)
    {
        fclose(source);
        printf("Could not open file\n");
        exit(EXIT_FAILURE);
    }

    printf("The contents of %s file are :\n", source_file);

    /*while ((ch = fgetc(source)) != EOF)
        printf("%c", ch);
    printf("\n");*/

    qsort(contacts, ncontacts, sizeof contacts[0], CompareCity);

    while ((copy = fgetc(source)) != EOF)
        fputc(copy, target);

    printf("File copied successfully.\n");

    printf("The contents of %s file are :\n", target_file);

    /*while ((show = fgetc(target)) != EOF) 
        printf("%c", show);
    printf("\n");*/

    fclose(source);
    fclose(target);

    return 0;
}

int CompareCity(void *pa, void *pb) {

    return strcmp(((ContactType*)pa)->city, ((ContactType*)pb)->city);
}

【问题讨论】:

  • 你知道谁有 1000 个字母的名字吗?等等……对于结构中的领域来说,这些是非常热情的数字。
  • 另外,fgetc 返回 int 而不是 char
  • Why is the gets() function too dangerous to use? 你最好使用标准C 函数fgets() 或POSIX 函数getline() 来读取行。在使用数据之前不要忘记检查输入函数是否成功。并且错误信息最好打印在标准错误上(stderr);这就是它的用途。
  • 嗯,好的,谢谢@JonathanLeffler 的建议。此外,我只是想保持所有数组的大小一致,但如果需要,我可以更改它。
  • 不需要改;太大总比太小好(例如,如果你选择 20 而不是 1000,我会有不同的智慧的话)。但是,当几乎任何地址都适合低于 1 K 时,使用 7 K 的内存有点过高。但是您可以使代码在您拥有的大小下正常工作。您要将源文件中的行读入 char 数组,然后将字段拆分为结构数组。它们是制表符分隔的字段;您可能只使用strtok(),但一般来说这不是一个好的例程(在 SO dissing 上找到答案)。

标签: c sorting text-files


【解决方案1】:

回答您关于注释代码的问题:

每个打开的文件都有一个file pointer 的概念,表示读/写操作发生的当前位置。

对于第一个注释代码:

while ((ch = fgetc(source)) != EOF)
    printf("%c", ch);
printf("\n");

从文件中输入所有字符后,文件指针位于文件末尾。

上面的代码尝试读取文件。但是,文件指针已经在文件末尾了。

建议在读取/解析/排序文件之前使用rewind()(或更好)lseek() 将文件指针移回文件开头。

第二个注释代码:

while ((show = fgetc(target)) != EOF) 
    printf("%c", show);
printf("\n");

有一个类似的问题,同样,文件指针已经在新文件的末尾。

顺便说一句:fgetc() 返回一个 'int' 而 EOF 是一个 int,所以 ch 的声明和 show 的声明必须是 'int' 而不是 'char'。并且 EOF 不能正确地与“字符”进行比较。无需对代码进行其他更改即可处理声明为“int”而不是“char”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    相关资源
    最近更新 更多