C语言 如何排序文件输出



我有一个程序,它接受用户输入并创建带有用户输入的几个字段的记录。要求用户输入此人的姓和名、地址、城市、州、邮政编码和电话号码。我正试着按照每条记录所在城市的字母顺序对这些记录进行排序。我该怎么做呢?我对如何根据一个变量进行排序然后正确打印整个记录感到非常困惑。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct Record Record;
struct Record
    {
        char fname[51];
        char lname[51];
        char address[51];
        char city[51];
        char state[51];
        char zipcode[51];
        char phoneNumber[51];
        Record *next;
    };

int main()
{
    FILE *fileWriter;
    const char filename[] = "data.txt";
    char answer = '';
    Record *records = NULL;
    Record *records_first = NULL;
    Record *records_previous = NULL;
    fileWriter = fopen(filename,"wt");
    if(fileWriter != NULL) {
        for( ; ; ) {
            records = (Record*) malloc(sizeof(Record));  
            if(records_first == NULL)
                records_first = records;
            if(records_previous != NULL)
                records_previous->next = records;
            records = records_first;
            printf("First Name: n");
            scanf("%s", records->fname);
            fprintf(fileWriter,"%st",records->fname);
            printf("Last Name: n");
            scanf("%s", records->lname);
            fprintf(fileWriter,"%st",records->lname);
            printf("Address: n");
            scanf(" %[^n]", records->address);
            fprintf(fileWriter,"%st",records->address);
            printf("City: n");
            scanf("%s", records->city);
            fprintf(fileWriter,"%st",records->city);
            printf("State: n");
            scanf("%s", records->state);
            fprintf(fileWriter,"%st",records->state);
            printf("Zipcode: n");
            scanf("%s", records->zipcode);
            fprintf(fileWriter,"%st",records->zipcode);
            printf("Phone Number: n");
            scanf("%s", records->phoneNumber);
            fprintf(fileWriter,"%stn",records->phoneNumber);
            records->next = NULL;
            records_previous = records;
            printf("Are there anymore records? [y/n] ");
            scanf(" %c", &answer);
            if(tolower(answer) != 'y') {
                free(records);
                fclose(fileWriter);
                break;
            }
        }
    } else
        printf("Error opening file.");
    return 0;
}
                        **Edited Version**

我尝试使用qsort()。但最后出现了一个致命的错误。最重要的是,当我只能排序一个字段时,我如何正确打印整个记录?

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
struct Record
    {
        char fname[51];
        char lname[51];
        char address[51];
        char city[51];
        char state[51];
        int zipcode;
        int phoneNumber;
    };
int compare_city(const void *const p1, const void *const p2)
 {
    struct Record *r1 = (struct Record *) p1;
    struct Record *r2 = (struct Record *) p1;
    return strcmp(r1->city, r2->city);
 }

int main()
{
    FILE *fileWriter;
    const char filename[] = "data.txt";
    char answer = 'y';
    int size = 1;
    int i = 0;
    int count = 1;
    struct Record *records = NULL;
    struct Record *records_temp = NULL;

    fileWriter = fopen(filename,"wb");
    if(fileWriter != NULL)
        while(answer == 'y' || answer == 'Y')
        {
            if(records_temp == NULL)
            {
                struct Record *records_temp = realloc(records,(size)*sizeof(*records));
            }
            records = records_temp;
            printf("First Name: n");
            scanf("%s", records[i].fname);

            printf("Last Name: n");
            scanf("%s", records[i].lname);

            printf("Address: n");
            scanf(" %[^n]", records[i].address);

            printf("City: n");
            scanf("%s", records[i].city);

            printf("State: n");
            scanf("%s", records[i].state);

            printf("Zipcode: n");
            scanf("%s", records[i].zipcode);

            printf("Phone Number: n");
            scanf("%s", records[i].phoneNumber);
            //stores all record info
            printf("Are there anymore records? [y/n] ");
            scanf(" %c", &answer);

        if(tolower(answer) == 'y')
        {
            i++;
            count++;
        }
        for(i = 0; i < count ; i++)
        {
            qsort(records, count, sizeof(struct Record), compare_city);
            fprintf(fileWriter,"%sn",records[i].fname);
            fprintf(fileWriter,"%sn",records[i].lname);
            fprintf(fileWriter,"%sn",records[i].address);
            fprintf(fileWriter,"%sn",records[i].city);
            fprintf(fileWriter,"%sn",records[i].state);
            fprintf(fileWriter,"%dn",records[i].zipcode);
            fprintf(fileWriter,"%dn",records[i].phoneNumber);
        }
        free(records);
    }
    return 0;
}

事实上,你有一个列表结构,它不能用qsort()排序,但你可以使用数组代替,并通过使用malloc() + realloc()动态分配它。

要对条目进行排序,您可以使用qsort(),例如,假设您希望按名字排序,那么

int compare_first_name(const void *const p1, const void *const p2)
 {
    struct Record *r1 = (struct Record *) p1;
    struct Record *r2 = (struct Record *) p1;
    return strcmp(r1->fname, r2->fname);
 }

qsort(base, count, sizeof(struct Record), compare_first_name);

与大多数列表"添加"一样,通常很少有关于如何在许多情况下对列表实现来说是唯一的的快速解释。

在我们看一下按顺序读取列表数据之前(在你的问题中是按城市),让我们看一下一些基础知识,这些基础知识将有助于处理列表。首先,将输入save/output例程分开,这几乎总是这样。在您的情况下,您正在打开文件以"wt"模式保存。这意味着每次调用输入函数时,都要清除文件中所有现有的数据,只写入所读取的新值。虽然这对于您在main中的一次输入很好,但这几乎是不现实的。

此外,在处理列表时,您的代码会很快变得相当长。试图在main中做到这一切会让你发疯。这必然意味着创建一个函数来处理您需要的不同列表操作。(这将有助于使您的代码更易于管理和可读性。将现有代码移到insert_records之类的地方来处理从stdin收集输入就可以了。将输入处理移到函数中并对文件输出进行修剪的示例如下:

size_t insert_records (Record **records)
{
    // FILE *fileWriter;
    // const char filename[] = "dat/lldata.txt";
    char answer = 0;
    // Record *records = NULL;
    // Record *records_first = NULL;
    // Record *records_previous = NULL;
    Record *iter = NULL;
    size_t cnt = 0;
/*
    if (!(*filename)) {
        printf ("nEnter filename for list data: ");
        scanf (" %m[^n]%*c", filename);
    }
    if (!(fileWriter = fopen (*filename, "at"))) {
        fprintf (stderr, "%s() error: invalid filename '%s' (file not found).n", 
                __func__, *filename);
        return 0;
    }
*/
    if (*records) {
        iter = *records;
        while (iter->next) iter = iter->next;
    }
    for (;;) 
    {
        Record *rec = malloc (sizeof *rec);     /* use malloc correctly */
        if (!rec) {
            fprintf (stderr, "%s() error: memory exhausted.n", __func__);
            return 0;
        }
        printf ("n  First Name: ");
        scanf (" %[^n]%*c", rec->fname);    /* fix scanf format strings */
        // fprintf (fileWriter, "%st", rec->fname);
        printf ("   Last Name: ");
        scanf ("%[^n]%*c", rec->lname);
        // fprintf (fileWriter, "%st", rec->lname);
        printf ("     Address: ");
        scanf ("%[^n]%*c", rec->address);
        // fprintf (fileWriter, "%st", rec->address);
        printf ("        City: ");
        scanf ("%[^n]%*c", rec->city);
        // fprintf (fileWriter, "%st", rec->city);
        printf ("       State: ");
        scanf ("%[^n]%*c", rec->state);
        // fprintf (fileWriter, "%st", rec->state);
        printf ("     Zipcode: ");
        scanf ("%[^n]%*c", rec->zipcode);
        // fprintf (fileWriter, "%st", rec->zipcode);
        printf ("Phone Number: ");
        scanf ("%[^n]%*c", rec->phoneNumber);
        // fprintf (fileWriter, "%stn", rec->phoneNumber);
        rec->next = NULL;
        if (!*records) {
            iter = *records = rec;
        } else {
            iter->next = rec;
            iter = iter->next;
        }
        cnt++;
        printf ("nEnter additional records? [y/n] ");
        scanf (" %c%*c", &answer);
        if (answer == 'n' || answer == 'N') { /* why include ctype.h for this? */
            // free (records);
            // fclose (fileWriter);
            break;
        }
    }
    return cnt;
}

注意返回类型被声明为size_t,因此您可以返回成功输入的记录数(它永远不能是负数,因此int不是您的最佳选择)。另外注意函数将列表指针的地址(即Record **records)作为参数,这是需要的,任何时候你都可以改变列表中的第一个(开始)节点(除非你使用一个单独的虚拟指针作为具有不同地址的第一个节点)。

要将列表保存到文件中,单独的例程可以提供更好的保护,防止意外的数据覆盖。只需要一个小的save_list函数。(注意 filename指针地址的传递方式与上面的records类似,因此它可以在函数本身中更改和更新。

size_t save_list (Record *rec, char **filename)
{
    if (!rec) {
        fprintf (stderr, "%s() error: list is empty.n", __func__);
        return 0;
    }
    FILE *fp = NULL;
    Record *iter = rec;
    size_t cnt = 0;
    if (!(*filename)) {
        printf ("nEnter filename for list data: ");
        scanf (" %m[^n]%*c", filename);
    }
    if (!(fp = fopen (*filename, "wt"))) {
        fprintf (stderr, "%s() error: invalid filename '%s' (file not found).n", 
                __func__, *filename);
        return 0;
    }
    for (; iter; iter = (iter->next ? iter->next : NULL))
    {
        fprintf (fp, "%s", iter->fname);
        fprintf (fp, "t%s", iter->lname);
        fprintf (fp, "t%s", iter->address);
        fprintf (fp, "t%s", iter->city);
        fprintf (fp, "t%s", iter->state);
        fprintf (fp, "t%s", iter->zipcode);
        fprintf (fp, "t%sn", iter->phoneNumber);
        cnt++;
    }
    fclose (fp);
    return cnt;
}

将数据保存到文件中是非常无用的,除非你可以将其读回程序中。由于我们将根据将数据读入列表的第二个副本进行排序,因此将数据读入程序的示例输入例程可以是:

size_t read_records (Record **records, char **filename)
{
    FILE *fp = NULL;
    Record *iter = NULL;
    size_t cnt = 0;
    if (!(*filename)) {
        printf ("nEnter filename for list data: ");
        scanf (" %m[^n]%*c", filename);
    }
    if (!(fp = fopen (*filename, "r"))) {
        fprintf (stderr, "%s() error: invalid filename '%s' (file not found).n", 
                __func__, *filename);
        if (*filename) free (*filename);    /* prevent returning invalid name */
        *filename = NULL;
        return 0;
    }
    if (*records) {
        iter = *records;
        while (iter->next) iter = iter->next;
    }
    for (;;)
    {
        Record *rec = malloc (sizeof *rec);
        if (!rec) {
            fprintf (stderr, "%s() error: memory exhausted.n", __func__);
            return 0;
        }
        if (fscanf (fp, " %[^t] %[^t] %[^t] %[^t] %[^t] %[^t] %[^n]%*c",
                rec->fname, rec->lname, rec->address, rec->city, rec->state,
                rec->zipcode, rec->phoneNumber) != 7)
        {
            free (rec);
            break;
        }
        rec->next = NULL;
        if (!*records) {
            iter = *records = rec;
        } else {
            iter->next = rec;
            iter = iter->next;
        }
        cnt++;
    }
    fclose (fp);
    return cnt;
}

在您将数据读入列表之后,有一些方法来查看它将会很有帮助:

void prn_records (Record *records)
{
    if (!records) return;
    Record *iter = records;
    size_t cnt = 0;
    while (iter) {
        printf ("n    record[%3zu]:nn", cnt);
        printf ("t%s, %sn", iter->lname, iter->fname);
        printf ("t%sn", iter->address);
        printf ("t%s, %s %sn", iter->city, iter->state, iter->zipcode);
        printf ("t%sn", iter->phoneNumber);
        cnt++;
        iter = iter->next;
    }
}
现在我们可以讨论你问题的关键了。如何按城市排序列表数据。正如您所发现的,没有办法qsort链表,虽然您可以将列表转换为array of structs,然后将qsort转换为结构体数组,但将数据以排序顺序()读入列表的第二个副本同样容易。这基本上只不过是修改read_records函数,以根据城市按字母顺序插入记录。有更优雅的方法可以将指针传递给泛型read函数,以允许对任何成员进行排序,但对于这里的目的,使用一个单独的函数对city进行排序就足够了:
size_t read_city_sorted (Record **records, char **filename)
{
    FILE *fp = NULL;
    Record *iter = NULL;
    size_t cnt = 0;
    size_t inserted = 0;
    if (!(*filename)) {
        printf ("nEnter filename for list data: ");
        scanf (" %m[^n]%*c", filename);
    }
    if (!(fp = fopen (*filename, "r"))) {
        fprintf (stderr, "%s() error: invalid filename '%s' (file not found).n", 
                __func__, *filename);
        if (*filename) free (*filename);    /* prevent returning invalid name */
        *filename = NULL;
        return 0;
    }
    for (;;)
    {
        inserted = 0;
        Record *rec = malloc (sizeof *rec);
        if (!rec) {
            fprintf (stderr, "%s() error: memory exhausted.n", __func__);
            return 0;
        }
        rec->next = NULL;
        if (fscanf (fp, " %[^t] %[^t] %[^t] %[^t] %[^t] %[^t] %[^n]%*c",
                rec->fname, rec->lname, rec->address, rec->city, rec->state,
                rec->zipcode, rec->phoneNumber) != 7)
        {
            free (rec);
            break;
        }
        if (!*records) {    /* if no records insert as first */
            *records = rec;
        } else 
        {
            iter = *records;
            /* use strcmp to find location of city in sorted list */
            while ((strcmp (iter->city, rec->city) < 0) && iter->next) 
            {   
                /* check if alphetical order between iter & iter->next */
                if (strcmp (rec->city, iter->next->city) < 0) 
                {
                    rec->next = iter->next; /* insert in order      */
                    iter->next = rec;
                    inserted = 1;           /* set inserted flag    */
                    break;
                }
                iter = iter->next;
            }
            if (!inserted) {
                if (iter == *records) {     /* insert at beginning  */
                    rec->next = *records;
                    *records = rec;
                }
                else {                      /* insert at end        */
                    iter->next = rec;
                }
            }
        }
        cnt++;
    }
    fclose (fp);
    return cnt;
}

现在,列表操作令人沮丧的部分是,有许多小细节要把拼图的各个部分放在一起,如果没有一些工作示例,上面的函数就只是函数。为了帮助解释,我编写了一个小的驱动程序来将这些部件连接在一起(由于必要的小部件,最终比最初计划的要长得多)。代码被注释了,最后还有一些注释。消化一下,如果有任何问题请告诉我。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #include <ctype.h>
typedef struct Record Record;
struct Record {             /* static arrays are fine, but inefficient  */
    char fname[51];
    char lname[51];
    char address[51];
    char city[51];
    char state[51];
    char zipcode[51];
    char phoneNumber[51];   /* avoid mixed caPs (camelCase) in C */
    Record *next;           /* avoid initial Caps (not a hanging offence) */
};
size_t insert_records (Record **records);
size_t read_records (Record **records, char **filename);
size_t read_city_sorted (Record **records, char **filename);
size_t save_list (Record *rec, char **filename);
void prn_records (Record *records);
void free_records (Record *rec);
int main (int argc, char **argv) {
    Record *records = NULL; /* list pointer for linked-list */
    Record *sorted = NULL;  /* list pointer for sorted linked-list */
    char *datafile = argc > 1 ? strdup (argv[1]) : NULL;
    char c = 0;
    size_t numrec = 0;      /* number of records in list */
    size_t sortrec = 0;     /* number of records in sorted list     */
    char *fname = NULL;     /* allow save in new filename   */
    char *sfname = NULL;    /* save sorted list in separate filename */
    if (datafile)       /* if filename given on command line, read */
        numrec = read_records (&records, &datafile);
    for (;;)
    {   /* quick menu for list operations */
        printf ("nSelect operation from list, 'q' when done:nn");
        printf ("t1)  Insert Records Manuallyn");
        printf ("t2)  Read Records from Filen");
        printf ("t3)  Read/Print Records from File (sorted on city)n");
        printf ("t4)  Show Number of Records in listn");
        printf ("t5)  Show Number of Records (sorted list)n");
        printf ("t6)  Print Recordsn");
        printf ("t7)  Print Sorted Records (on city)n");
        printf ("t8)  Save Records to Filen");
        printf ("t9)  Save (sorted ) Records to Filen");
        printf ("tq)  Quitn");
        printf ("n    selection: ");
        scanf (" %c%*c", &c);
        if (c == 'q' || c == 'Q') break;
        switch (c)
        {
            case '1' : numrec += insert_records (&records);
                break;
            case '2' : numrec += read_records (&records, &datafile);
                break;
            case '3' : sortrec = read_city_sorted (&sorted, &datafile);
                break;
            case '4' : printf ("n  The list contains '%zu' recordsn", numrec);
                break;
            case '5' : printf ("n  The (sorted list) contains '%zu' recordsn", sortrec);
                break;
            case '6' : prn_records (records);
                break;
            case '7' : prn_records (sorted);
                break;
            case '8' : save_list (records, &fname);
                break;
            case '9' : save_list (sorted, &sfname);
                break;
            default  : printf ("n error: invalid selectionn");
                break;
        }
    }
    if (sorted) free_records (sorted);  /* no forced save of sorted, up to you  */
    if (records) {
        save_list (records, &fname);    /* force save before free, save in new  */
        free_records (records);         /* fname to keep original datafile      */
    }
    if (fname) free (fname);
    if (sfname) free (sfname);
    if (datafile) free (datafile);
    return 0;
}
size_t read_records (Record **records, char **filename)
{
    FILE *fp = NULL;
    Record *iter = NULL;
    size_t cnt = 0;
    if (!(*filename)) {
        printf ("nEnter filename for list data: ");
        scanf (" %m[^n]%*c", filename);
    }
    if (!(fp = fopen (*filename, "r"))) {
        fprintf (stderr, "%s() error: invalid filename '%s' (file not found).n", 
                __func__, *filename);
        if (*filename) free (*filename);    /* prevent returning invalid name */
        *filename = NULL;
        return 0;
    }
    if (*records) {
        iter = *records;
        while (iter->next) iter = iter->next;
    }
    for (;;)
    {
        Record *rec = malloc (sizeof *rec);
        if (!rec) {
            fprintf (stderr, "%s() error: memory exhausted.n", __func__);
            return 0;
        }
        if (fscanf (fp, " %[^t] %[^t] %[^t] %[^t] %[^t] %[^t] %[^n]%*c",
                rec->fname, rec->lname, rec->address, rec->city, rec->state,
                rec->zipcode, rec->phoneNumber) != 7)
        {
            free (rec);
            break;
        }
        rec->next = NULL;
        if (!*records) {
            iter = *records = rec;
        } else {
            iter->next = rec;
            iter = iter->next;
        }
        cnt++;
    }
    fclose (fp);
    return cnt;
}
size_t read_city_sorted (Record **records, char **filename)
{
    FILE *fp = NULL;
    Record *iter = NULL;
    size_t cnt = 0;
    size_t inserted = 0;
    if (!(*filename)) {
        printf ("nEnter filename for list data: ");
        scanf (" %m[^n]%*c", filename);
    }
    if (!(fp = fopen (*filename, "r"))) {
        fprintf (stderr, "%s() error: invalid filename '%s' (file not found).n", 
                __func__, *filename);
        if (*filename) free (*filename);    /* prevent returning invalid name */
        *filename = NULL;
        return 0;
    }
    for (;;)
    {
        inserted = 0;
        Record *rec = malloc (sizeof *rec);
        if (!rec) {
            fprintf (stderr, "%s() error: memory exhausted.n", __func__);
            return 0;
        }
        rec->next = NULL;
        if (fscanf (fp, " %[^t] %[^t] %[^t] %[^t] %[^t] %[^t] %[^n]%*c",
                rec->fname, rec->lname, rec->address, rec->city, rec->state,
                rec->zipcode, rec->phoneNumber) != 7)
        {
            free (rec);
            break;
        }
        if (!*records) {    /* if no records insert as first */
            *records = rec;
        } else 
        {
            iter = *records;
            /* use strcmp to find location of city in sorted list */
            while ((strcmp (iter->city, rec->city) < 0) && iter->next) 
            {   
                /* check if alphetical order between iter & iter->next */
                if (strcmp (rec->city, iter->next->city) < 0) 
                {
                    rec->next = iter->next; /* insert in order      */
                    iter->next = rec;
                    inserted = 1;           /* set inserted flag    */
                    break;
                }
                iter = iter->next;
            }
            if (!inserted) {
                if (iter == *records) {     /* insert at beginning  */
                    rec->next = *records;
                    *records = rec;
                }
                else {                      /* insert at end        */
                    iter->next = rec;
                }
            }
        }
        cnt++;
    }
    fclose (fp);
    return cnt;
}
size_t insert_records (Record **records)
{
    // FILE *fileWriter;
    // const char filename[] = "dat/lldata.txt";
    char answer = 0;
    // Record *records = NULL;
    // Record *records_first = NULL;
    // Record *records_previous = NULL;
    Record *iter = NULL;
    size_t cnt = 0;
/*
    if (!(*filename)) {
        printf ("nEnter filename for list data: ");
        scanf (" %m[^n]%*c", filename);
    }
    if (!(fileWriter = fopen (*filename, "at"))) {
        fprintf (stderr, "%s() error: invalid filename '%s' (file not found).n", 
                __func__, *filename);
        return 0;
    }
*/
    if (*records) {
        iter = *records;
        while (iter->next) iter = iter->next;
    }
    for (;;) 
    {
        Record *rec = malloc (sizeof *rec);     /* use malloc correctly */
        if (!rec) {
            fprintf (stderr, "%s() error: memory exhausted.n", __func__);
            return 0;
        }
        printf ("n  First Name: ");
        scanf (" %[^n]%*c", rec->fname);    /* fix scanf format strings */
        // fprintf (fileWriter, "%st", rec->fname);
        printf ("   Last Name: ");
        scanf ("%[^n]%*c", rec->lname);
        // fprintf (fileWriter, "%st", rec->lname);
        printf ("     Address: ");
        scanf ("%[^n]%*c", rec->address);
        // fprintf (fileWriter, "%st", rec->address);
        printf ("        City: ");
        scanf ("%[^n]%*c", rec->city);
        // fprintf (fileWriter, "%st", rec->city);
        printf ("       State: ");
        scanf ("%[^n]%*c", rec->state);
        // fprintf (fileWriter, "%st", rec->state);
        printf ("     Zipcode: ");
        scanf ("%[^n]%*c", rec->zipcode);
        // fprintf (fileWriter, "%st", rec->zipcode);
        printf ("Phone Number: ");
        scanf ("%[^n]%*c", rec->phoneNumber);
        // fprintf (fileWriter, "%stn", rec->phoneNumber);
        rec->next = NULL;
        if (!*records) {
            iter = *records = rec;
        } else {
            iter->next = rec;
            iter = iter->next;
        }
        cnt++;
        printf ("nEnter additional records? [y/n] ");
        scanf (" %c%*c", &answer);
        if (answer == 'n' || answer == 'N') { /* why include ctype.h for this? */
            // free (records);
            // fclose (fileWriter);
            break;
        }
    }
    return cnt;
}
void prn_records (Record *records)
{
    if (!records) return;
    Record *iter = records;
    size_t cnt = 0;
    while (iter) {
        printf ("n    record[%3zu]:nn", cnt);
        printf ("t%s, %sn", iter->lname, iter->fname);
        printf ("t%sn", iter->address);
        printf ("t%s, %s %sn", iter->city, iter->state, iter->zipcode);
        printf ("t%sn", iter->phoneNumber);
        cnt++;
        iter = iter->next;
    }
}
size_t save_list (Record *rec, char **filename)
{
    if (!rec) {
        fprintf (stderr, "%s() error: list is empty.n", __func__);
        return 0;
    }
    FILE *fp = NULL;
    Record *iter = rec;
    size_t cnt = 0;
    if (!(*filename)) {
        printf ("nEnter filename for list data: ");
        scanf (" %m[^n]%*c", filename);
    }
    if (!(fp = fopen (*filename, "wt"))) {
        fprintf (stderr, "%s() error: invalid filename '%s' (file not found).n", 
                __func__, *filename);
        return 0;
    }
    for (; iter; iter = (iter->next ? iter->next : NULL))
    {
        fprintf (fp, "%s", iter->fname);
        fprintf (fp, "t%s", iter->lname);
        fprintf (fp, "t%s", iter->address);
        fprintf (fp, "t%s", iter->city);
        fprintf (fp, "t%s", iter->state);
        fprintf (fp, "t%s", iter->zipcode);
        fprintf (fp, "t%sn", iter->phoneNumber);
        cnt++;
    }
    fclose (fp);
    return cnt;
}
void free_records (Record *rec)
{
    if (!rec) {
        fprintf (stderr, "%s() error: list is empty.n", __func__);
        return;
    }
    Record *iter = rec;
    Record *victim = NULL;
    while (iter) 
    {
        victim = iter;
        iter = iter->next;
        if (victim) free (victim);
    }
}

使用/输出示例

注:要读取的数据文件可以作为参数提供给程序,也可以选择2) Read Records from File并输入文件名。还要注意,代码强制在退出时将原始列表数据保存在一个新文件名下。这将保持原始数据文件不变。(退出时提示输入新的文件名)

$ ./bin/ll_ins_sort dat/lldata.txt
Select operation from list, 'q' when done:
        1)  Insert Records Manually
        2)  Read Records from File
        3)  Read/Print Records from File (sorted on city)
        4)  Show Number of Records in list
        5)  Show Number of Records (sorted list)
        6)  Print Records
        7)  Print Sorted Records (on city)
        8)  Save Records to File
        9)  Save (sorted ) Records to File
        q)  Quit
    selection: 3
<_snipped menu_>
    selection: 7
    record[  0]:
        James, George
        32 Jones Place
        Billings, Montana 30412
        901 992-2165
    record[  1]:
        Doe, Jane
        459 35th Street
        Bridge City, Colorado 78763
        303 534-6734
    record[  2]:
        Mayer, Alphred
        222 Two Lane
        Chemco, Texas 77722
        713 555-1212
    record[  3]:
        Jones, Jill
        4312 Meandering Way
        Dallas, Texas 75248
        214 789-5391
    record[  4]:
        Barnes, Bill
        227 North Street
        Moosejaw, Maine 10103
        312 832-2189
    record[  5]:
        Early, Robert
        13 Sunrise Ln.
        Sunset, California 80210
        505 555-1212
<_snipped menu_>
    selection: 9
Enter filename for list data: dat/lldatasort.txt
<_snipped menu_>
    selection: q
Enter filename for list data: dat/lldatanew.txt

原始输入(使用input_records创建)

$ cat dat/lldata.txt
Alphred Mayer   222 Two Lane    Chemco  Texas   77722   713 555-1212
George  James   32 Jones Place  Billings        Montana 30412   901 992-2165
Bill    Barnes  227 North Street        Moosejaw        Maine   10103   312 832-2189
Jane    Doe     459 35th Street Bridge City     Colorado        78763   303 534-6734
Jill    Jones   4312 Meandering Way     Dallas  Texas   75248   214 789-5391
Robert  Early   13 Sunrise Ln.  Sunset  California      80210   505 555-1212

在保存已排序

$ cat dat/lldatasort.txt
George  James   32 Jones Place  Billings        Montana 30412   901 992-2165
Jane    Doe     459 35th Street Bridge City     Colorado        78763   303 534-6734
Alphred Mayer   222 Two Lane    Chemco  Texas   77722   713 555-1212
Jill    Jones   4312 Meandering Way     Dallas  Texas   75248   214 789-5391
Bill    Barnes  227 North Street        Moosejaw        Maine   10103   312 832-2189
Robert  Early   13 Sunrise Ln.  Sunset  California      80210   505 555-1212

相关内容

  • 没有找到相关文章

最新更新