如何将txt文件(包含结构)复制到链表c

时间:2016-03-18 22:15:26

标签: c struct linked-list malloc

我是c编程的新手。在我的课程中,我必须建立一个数据库来存储学生。程序必须允许在链表中输入标记,id,名称和存储(作为结构),并且还存储在文件中,也可以从文件读入链表。我唯一的问题是,当我关闭.exe程序,然后选择从.txt文件读取到链表时,它不起作用。编译代码时没有错误,但是当我在后面选择所有学生的DISPLAY REPORT时,没有显示任何记录。这是一个小问题,请建议如何解决这个问题。

我的代码如下:

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

struct phbook
{
    int number;
    char name[20];
    int mark;
    struct part *next;
};

//struct phbook *find_student(int number);
//void insertFull(struct phbook* list, int number, char Name[10],int mark);

struct phbook* insert(struct phbook *list);
struct phbook* insertFull(struct phbook* list,
                          int number,
                          char Name[10],
                          int mark);
void readFile(struct phbook* list);

int main(void)
{
    struct phbook *list = NULL;
    int code;
    int opt1;
    int courses, i, k, j, counter;
    for (;;)
    {
        printf("Enter operation code: \n");
        printf("(1) ADD NEW STUDENT DETAILS: \n");
        printf("(2) SEARCH STUDENT DETAILS: \n");
        printf("(3) DISPLAY REPORT OF ALL STUDENTS: \n");
        printf("(4) SAVE ALL STUDENT RECORDS TO EXTERNAL FILE: \n");
        printf("(5) LOAD ALL STUDENT RECORDS FROM EXTERNAL FILE: \n");
        scanf(" %d", &code);
        switch (code)
        {
            case 1:
                list = insert(list);
                break;
            case 2: //search();
                break;
                break;
            case 3:
                print(list);
                break;
            case 4:
                saveToFile(list);
                break;
            case 5:
                readFile(list);
                break;
            default:
                printf("Illegal code\n");
        }
        printf("\n");
    }
}

/*struct phbook *find_student(int number)
 {
 struct phbook *p;
 for (p = list; p != NULL && number != p->number; p = p->next);//was sorted
 if (p != NULL && number == p->number)
 return p;
 return NULL;
 }*/

struct phbook* insert(struct phbook *list)
{

    struct phbook *cur;
    struct phbook *prev;
    struct phbook *new_node;
    new_node = (struct phbook*) malloc(sizeof(struct phbook));
    if (new_node == NULL)
    {
        printf("db full er1.\n");
        return NULL;
    }
    printf("enter student id");
    scanf("%d", &new_node->number);
    for (cur = list, prev = NULL; cur != NULL && new_node->number > cur->number;
            prev = cur, cur = cur->next)
        ;
    printf("Enter name: ");
    scanf("%s", &new_node->name); //readline(new_node->name, NAME_LEN)
    printf("Enter MARK: ");
    scanf("%d", &new_node->mark);

    new_node->next = cur;
    if (prev == NULL)
        list = new_node;
    else
        prev->next = new_node;

    return list;
}

void search(void)
{
    int number;
    struct phbook *p;
    printf("Enter ID: ");
    scanf("%d", &number);
    p = find_student(number);
    if (p != NULL)
    {
        printf("Name: %s\n", p->name);
        printf("Marks: %d\n", p->mark);
    }
    else
        printf("student not found.\n");
}

void print(struct phbook *list)
{
    struct phbook *p;
    printf("Student_Number Student_Name Student_Mark\n");
    for (p = list; p != NULL; p = p->next)
        printf("%7d %-25s %d\n", p->number, p->name, p->mark);
}

void saveToFile(struct phbook *list)
{
    FILE* fp;
    fp = fopen("results.txt", "w");

    struct phbook* cur = list; //he
    while (cur != NULL)
    {
        fprintf(fp, "%s\n", list->name);
        fprintf(fp, "%d\n", cur->number);
        fprintf(fp, "%d\n", cur->mark);
        cur = cur->next;
    }
    fclose(fp);
}

void readFile(struct phbook* list)
{
    FILE* fp;
    if (!(fp = fopen("results.txt", "r")))
        printf("File NOT Found");
    else
    {
        struct phbook *cur;
        struct phbook *prev;
        char TempName[10];
        int TempNumber;
        int TempMark;
        int done = 0;
        int count = 0;
        int success; //dummy
        cur = list; //sets it to the head (first nde of ll)
        if (list == NULL)
            ;
        printf("List is null\n");

        if (cur == NULL)
            printf("List is null\n");

        while (cur != NULL)
        {
            cur = cur->next;
        }
        while (done == 0)
        {
            success = fscanf(fp, "%s", TempName);
            if (success == 1)
            {
                success = fscanf(fp, "%d", &TempNumber);
                if (success == 1)
                {
                    success = fscanf(fp, "%d", &TempMark);

                    if (success == 1)
                    {
                        insertFull(list, TempNumber, TempName, TempMark);
                    }
                }

            }
            else
            {
                done = 1;
            }
        }
    }
}

struct phbook* insertFull(struct phbook* list,
                          int number,
                          char Name[10],
                          int mark)
{
    struct phbook *cur;
    struct phbook *prev;
    struct phbook *new_node;
    new_node = (struct phbook*) malloc(sizeof(struct phbook));
    if (new_node == NULL)
    {
        printf("db full er1.\n");
        return;
    }

    for (cur = list, prev = NULL; cur != NULL && new_node->number > cur->number;
            prev = cur, cur = cur->next)
        ;
    new_node->number = number;
    new_node->mark = mark;
    strcpy(new_node->name, Name);
    new_node->next = cur;
    if (prev == NULL)
        list = new_node;
    else
        prev->next = new_node;
    return list;
}
截图是这样的:

当我到达这里时,屏幕截图已经是MIA - user4581301

2 个答案:

答案 0 :(得分:1)

如果执行应用程序,主列表将为空。

当您再调用readFile()时,您将不会更新main中的列表。您只需按值传递指针,以便更新该函数的本地参数。顺便说一句,对insertFull()的调用有几乎相同的问题:它在插入后返回列表,但是你忽略了这个返回。

更改这两个函数,以便它们都返回列表,就像您对insert()所做的那样:

struct phbook* readFile(struct phbook* list) 
{
    ...
             list = insertFull(list, TempNumber, TempName, TempMark);
    ...
    return list; 
}

当然,在开始时调整你的函数原型,并更新菜单处理:

        case 5:
            list = readFile(list);
            break;

答案 1 :(得分:0)

以下代码干净地编译

但是,它不会链接,因为函数:find_student()已被注释掉。

检查代码表明它不能完全执行所有所需的功能。所以你仍然需要调试执行。

建议使用调试器,例如gdb

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

#define MAX_NAME_LEN (20)

struct phbook
{
    int studentID;
    char studentName[ MAX_NAME_LEN ];
    int studentGrade;
    struct phbook *next;
};

// prototypes
struct phbook* insert(struct phbook* );
struct phbook* find_student( int );
void insertFull( struct phbook*, int, char *, int );
void readFile  ( struct phbook* );
void print     ( struct phbook* );
void saveToFile( struct phbook* );


int main(void)
{
    struct phbook *list = NULL;
    int code;

    for (;;)
    {
        printf("Enter operation code: \n");
        printf("(1) ADD NEW STUDENT DETAILS: \n");
        printf("(2) SEARCH STUDENT DETAILS: \n");
        printf("(3) DISPLAY REPORT OF ALL STUDENTS: \n");
        printf("(4) SAVE ALL STUDENT RECORDS TO EXTERNAL FILE: \n");
        printf("(5) LOAD ALL STUDENT RECORDS FROM EXTERNAL FILE: \n");
        scanf(" %d", &code);

        switch (code)
        {
            case 1:
                list = insert(list);
                break;

            case 2: //search();
                break;
                break;

            case 3:
                print(list);
                break;

            case 4:
                saveToFile(list);
                break;

            case 5:
                readFile(list);
                break;

            default:
                printf("Illegal code\n");
        } // end switch

        printf("\n");
    } // end for()
} // end function: main


#if 0
struct phbook *find_student(int studentID)
{
    struct phbook *p;
    for (p = list; p != NULL && studentID != p->studentID; p = p->next);//was sorted

    return p;
} // end function: find_student
#endif


struct phbook* insert(struct phbook *list)
{
    struct phbook *cur;
    struct phbook *prev;
    struct phbook *new_node;

    if( NULL == (new_node = malloc(sizeof(struct phbook)) ) )
    {
        perror( "malloc for struct phbook failed");
        return NULL;
    }

    // implied else malloc successful

    printf("enter student id");
    scanf("%d", &new_node->studentID);

    for (cur = list, prev = NULL;
        cur != NULL && new_node->studentID > cur->studentID;
        prev = cur, cur = cur->next)
    {
        ;
    }

    printf("Enter studentName: ");
    scanf("%19s", new_node->studentName); //readline(new_node->studentName, NAME_LEN)

    printf("Enter MARK: ");
    scanf("%d", &new_node->studentGrade);

    new_node->next = cur;

    if (!prev)
    {
        list = new_node;
    }

    else
    {
        prev->next = new_node;
    }

    return list;
} // end function: search


void search(void)
{
    int studentID;
    struct phbook *p;
    printf("Enter ID: ");
    scanf("%d", &studentID);

    if( NULL == (p = find_student(studentID) ) )
    {
        printf("studentName: %s\n", p->studentName);
        printf("Marks: %d\n", p->studentGrade);
    }

    else
    {
        printf("student not found.\n");
    }
} // end function: search


void print(struct phbook *list)
{
    struct phbook *p;
    printf("Student_Number Student_studentName Student_Mark\n");
    for (p = list; p != NULL; p = p->next)
        printf("%7d %-25s %d\n", p->studentID, p->studentName, p->studentGrade);
} // end function: print


void saveToFile(struct phbook *list)
{
    FILE* fp;
    fp = fopen("results.txt", "w");

    struct phbook* cur = list; //he
    while (cur != NULL)
    {
        fprintf(fp, "%s\n", list->studentName);
        fprintf(fp, "%d\n", cur->studentID);
        fprintf(fp, "%d\n", cur->studentGrade);
        cur = cur->next;
    }
    fclose(fp);
} // end function: saveToFile


void readFile( struct phbook* list)
{
    FILE* fp = NULL;
    if (!(fp = fopen("results.txt", "r")))
    {
        perror( "fopen for read of results.txt failed");
        return;
    }

    //implied else, fopen successful

    char TempstudentName[10];
    int TempNumber;
    int TempMark;

    while (3 == fscanf(fp, " %19s %d %d", TempstudentName, &TempNumber, &TempMark ) )
    {
        insertFull(list, TempNumber, TempstudentName, TempMark);
    }
} // end function; readFile


void insertFull(struct phbook* list,
                          int  studentID,
                          char studentName[10],
                          int  studentGrade)
{
    struct phbook *cur;
    struct phbook *prev;
    struct phbook *new_node;

    if( NULL == (new_node = malloc(sizeof(struct phbook)) ) )
    {
        perror( "malloc for size of struct phbook failed" );
        return;
    }

    for (cur = list, prev = NULL;
        cur != NULL && new_node->studentID > cur->studentID;
        prev = cur, cur = cur->next)
    {
        ;
    }

    new_node->studentID = studentID;
    new_node->studentGrade = studentGrade;
    strcpy(new_node->studentName, studentName);
    new_node->next = cur;

    if (!prev)
    {
        list = new_node;
    }

    else
    {
        prev->next = new_node;
    }
} // end function: insertFull

我没有添加所有必要的错误检查,所以你必须这样做。

我添加了缺少的原型

我纠正了几个小的编码错误