在C语言中将链表数据写入文本文件

3
我创建了一个程序,首先询问您拥有多少宠物,然后在结构体中存储每个宠物的名称和年龄(都使用链表)。
我的问题是:我尝试使用过程"writeToFile()"将数据写入.txt文件,但在执行时,.txt文件不包含任何数据。我不明白为什么?
这是我的代码:
#include <stdio.h>
#include <stdlib.h>

struct Node {
    char *name;
    int age;
    struct Node *next;
};

struct Node * petRecord;
struct Node * newRecord;

void printPetRecord()
{  
    while(petRecord != NULL)
    {
        printf("Name of Pet: %s\n", petRecord->name);
        printf("Age of Pet: %d\n", petRecord->age);
        petRecord = petRecord->next;
    }
}

void writeToFile()
{
    FILE * fptr;
    fptr = fopen("petnames.txt", "w");

    if(fptr==NULL)
    {
        printf("Error\n");
    }

    else
    {
        while(petRecord != NULL)
        {
            fprintf(fptr, "\nPet Name: %s\nAge: %d\n", petRecord->name, petRecord->age);
            petRecord = petRecord->next;
        }
    }

    fclose(fptr);
    }

int main()
{ 
    int count, i;
    printf("How many pets do you have? ");
    scanf("%d", &count);

    for(i=0; i<count; i++)
    {
        if(i==0)
        {
            petRecord = malloc(sizeof(struct Node));
            newRecord = petRecord;
        }
        else
        {
            newRecord->next = malloc(sizeof(struct Node));
            newRecord = newRecord->next;
        }
        newRecord->name = malloc(50*sizeof(char));
        printf("Name of Pet: ");
        scanf("%s", newRecord->name);
        printf("Age of Pet: ");
        scanf("%d", &newRecord->age);
    }
    newRecord->next = NULL;
    printf("\n\n");
    printPetRecord();
    writeToFile();
}

1
你尝试过在标准输出上打印它吗? - Eugene Sh.
不要使用全局变量。 - n. m.
@Katrina:当你直接使用全局变量进行迭代时,你已经失去了列表头。 - developer
2个回答

3

您的 printPetRecord() 函数会将指针设为空值。

在 printPetRecord() 函数内部增加如下内容:

struct Node * iterator = petRecord;

然后使用迭代器进行迭代。

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

struct Node {
    char *name;
    int age;
    struct Node *next;
};

struct Node * petRecord;
struct Node * newRecord;

void printPetRecord()
{
    struct Node * iterator = petRecord;
    while(iterator != NULL)
    {
        printf("Name of Pet: %s\n", iterator->name);
        printf("Age of Pet: %d\n", iterator->age);
        iterator=iterator->next;
    }
}

void writeToFile()
{
    FILE * fptr;
    fptr = fopen("petnames.txt", "w");
    struct Node * iterator = petRecord;

    if(fptr==NULL)
    {
        printf("Error\n");
    }

    else
    {
        while(iterator!= NULL)
        {
            fprintf(fptr, "\nPet Name: %s\nAge: %d\n", iterator->name, iterator->age);
            iterator= iterator->next;
        }
    }

    fclose(fptr);
    }

int main()
{
    int count, i;
    printf("How many pets do you have? ");
    scanf("%d", &count);

    for(i=0; i<count; i++)
    {
        if(i==0)
        {
            petRecord = malloc(sizeof(struct Node));
            newRecord = petRecord;
        }
        else
        {
            newRecord->next = malloc(sizeof(struct Node));
            newRecord = newRecord->next;
        }
        newRecord->name = malloc(50*sizeof(char));
        printf("Name of Pet: ");
        scanf("%s", newRecord->name);
        printf("Age of Pet: ");
        scanf("%d", &newRecord->age);
    }
    newRecord->next = NULL;
    printf("\n\n");
    printPetRecord();
    writeToFile();
}

执行:

> gcc -o main main.c
> ./main
How many pets do you have? 2
Name of Pet: a
Age of Pet: 2
Name of Pet: b
Age of Pet: 3


Name of Pet: a
Age of Pet: 2
Name of Pet: b
Age of Pet: 3
> cat petnames.txt

Pet Name: a
Age: 2

Pet Name: b
Age: 3

3
这再次表明全局变量是有害的。 - Jabberwocky
通过这个操作[struct Node * iterator = petRecord],我创建了一个新的节点,它指向我的链表中第一个值的地址。所以,要将数据写入txt文件,我应该这样做:while(iterator != NULL) { fprintf(fptr, "\nPet Name: %s\nAge: %d\n", iterator->name, iterator->age); iterator = iterator->next; } 然而,我仍然没有任何数据在我的文件中:/ - zuzu
没问题,可以运行 :) - Oo.oO
我会再次检查一下!谢谢大家 :) - zuzu

1

三年七个月后,我在解决将链表数据写入.txt文件的问题时遇到了这个问题。 我来这里寻求解决方案,但是这个问题还没有接受任何答案。 因此,在这里我将尝试回答这个问题。

  1. 程序中不需要全局变量。
  2. 向程序中的函数发送一些参数,这将使您的任务更加容易。
  3. 在这些函数内部进行迭代时,通过执行 petRecord = petRecord->nextnewRecord = newRecord->next 会导致您失去 head 结构变量。这是由于全局变量造成的。因此,为了避免这种情况,在调用的函数内部每次声明一个 struct Node 类型的 local 指针变量。
  4. 如果您知道 char 数组的确切大小,则不要执行以下操作:newRecord->name = malloc(50*sizeof(char));,而是修改您的 struct 模板为 char name[50]。这比使用指针和动态分配要容易得多,因为在后一种情况下,您需要额外注意和预防。
  5. main() 函数中打开要写入 data 的文件,并将其发送到函数 writeToFile()
  6. 处理 strings 时应特别小心。
  7. 在分配内存或打开文件时,值得检查错误。因此,每次在程序中执行任何这些操作时,最好检查是否发生了任何错误。

为什么不试试这个程序:
#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    char name[50];
    int age;
    struct Node *next;
}Node;

// user-defined functions
void printPetRecord(Node *head);
void writeToFile(FILE *fptr, Node *head);

// main()
int main(void)
{
    int count, i;
    Node *petRecord, *newRecord;
    FILE *fp;

    if( (petRecord = malloc(sizeof(Node))) == NULL )
    {
        fprintf(stderr, "Unable to allocate memory.\n");
        exit(2);
    }
    newRecord = petRecord;
    printf("How many pets do you have? ");
    scanf("%d", &count);

    for(i = 0; i < count; i++)
    {
        printf("Name of Pet: ");
        scanf("%50s", newRecord->name);
        printf("Age of Pet: ");
        scanf("%d", &newRecord->age);
        if(i == count-1)
        {
            newRecord->next = NULL;
        }
        else
        {
            if( (newRecord->next = malloc(sizeof(Node))) == NULL)
            {
                fprintf(stderr, "Memory Unavailable.\n");
                exit(3);
            }
        }
        newRecord = newRecord->next;
    }
    printf("\n\n");
    // Modified arguments
    printPetRecord(petRecord);

    // Open file before sending to writeToFile
    if(!(fp = fopen("petname.txt", "w")))
    {
        fprintf(stderr, "Unable to open file \"petname.txt\"\n");
        exit(1);
    }
    // Modified arguments
    writeToFile(fp, petRecord);
    
    fclose(fp);
    return 0;
}

// function to print linked_list
void printPetRecord(Node *head)
{
    if(head->next != NULL)
    {
        printf("Name of Pet: %s\nAge of Pet: %d\n", head->name, head->age);
        printPetRecord(head->next);
    }
    else
        printf("Name of Pet: %s\nAge of Pet: %d\n", head->name, head->age);
}

// function to print list to file
void writeToFile(FILE *fptr, Node *head)
{
    if(head->next != NULL)
    {
        fprintf(fptr, "\nPet Name: %s\nAge: %d\n\n", head->name, head->age);
        writeToFile(fptr, head->next);
    }
    else
        fprintf(fptr, "\nPet Name: %s\nAge: %d\n\n", head->name, head->age);
}

输出(在控制台上):

How many pets do you have? 3
Name of Pet: Tommy
Age of Pet: 3
Name of Pet: Julia
Age of Pet: 4
Name of Pet: Hedgehog
Age of Pet: 5


Name of Pet: Tommy
Age of Pet: 3
Name of Pet: Julia
Age of Pet: 4
Name of Pet: Hedgehog
Age of Pet: 5

输出(在petname.txt文件中):


Pet Name: Tommy
Age: 3


Pet Name: Julia
Age: 4


Pet Name: Hedgehog
Age: 5


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接