将单词保存到C中的链接列表的问题 [英] Issue with saving words to linked lists in C

查看:48
本文介绍了将单词保存到C中的链接列表的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

typedef struct node
{
    int priorityc;
    char *itemName;
    struct node *next;
} node;
node *head;

void save();
void printcontents();
int search(char *itemName);
int serve(char *itemName);
void load();
void inserted();
void deleted(char *itemName);

int main()
{
    load();
    printcontents();
    save();
}

void load()
{
    head = NULL;
    FILE *fp;
    fp = fopen("California.txt", "r");
    int tempPriority;
    char tempName[200];

    while(fscanf(fp, "%s %d", tempName, &tempPriority) == 2)
    {
        //The issue seems to arise somewhere in the remaining code of the load function
        node *tempNode = (node *)malloc(sizeof(struct node));
        tempNode->priorityc = tempPriority;
        tempNode->itemName = tempName;
        tempNode->next = head;
        head = tempNode;
        printf("%s\n", head->itemName);
    }
    fclose(fp);
    printf("%s\n", head->itemName);
}

void printcontents()
{

    node *current = head;
    while(current != NULL)
    {
        printf("%s %d\n", current->itemName, current->priorityc);
        current=current->next;
    }
}

void save()
{
    FILE *fp;
    node *current = head;
    fp = fopen("California.txt", "w");
    while(current != NULL)
    {
        fprintf(fp, "%s %d\n", current->itemName, current->priorityc);
        current=current->next;
    }
    fclose(fp);
}

输入文件aka California.txt是一个简单的记事本文件,其中包含以下信息.

The input file aka California.txt is a simple notepad file with the following information.

Desktop-computer 100
Desktop-screen 100
Desktop-keyboard 100
TV-set 80
Audio-system 75
Bed 65
Night-table 65
Hibachi 35

保存功能完成后,所有数字都可以通过,但以下是控制台打印出的内容以及在California.txt文件上重写的内容.

After the save function all the numbers do make it through but the following is what the console prints out and what is rewritten on the California.txt file.

{°@u&0@ 35
{°@u&0@ 65
{°@u&0@ 65
{°@u&0@ 75
{°@u&0@ 80
{°@u&0@ 100
{°@u&0@ 100
{°@u&0@ 100

我试图将char tempName(在加载中找到的字符串)制作为指针并运行类似的函数,但随后控制台打印出并保存到加利福尼亚文件.

I tried to making char tempName (string found in load) into a pointer and running the function like that but then the console prints out and saves to california file.

Hibachi 35
Hibachi 65
Hibachi 65
Hibachi 75
Hibachi 80
Hibachi 100
Hibachi 100
Hibachi 100

我真的陷入了死胡同,我不知道该如何解决该问题,任何建议都会有所帮助.如果运行正常,则应将以下内容打印到控制台.

I've really run into a dead end here and I can't figure out how to fix the problem, any advice would help. If it was working correctly it should print out the following to the console.

Hibachi 35
Night-table 65
Bed 65
Audio-system 75
TV-set 80
Desktop-keyboard 100
Desktop-screen 100
Desktop-computer 100

推荐答案

您可能会误以为您的赋值语句:

You may be under the false impression that your assignment statement:

tempNode->itemName = tempName;

将整个字符串从一个位置复制到另一个位置.在许多其他编程语言中,可能是这种情况.在C中不是这样.

copies the entire string from one place to another. In many other programming languages this may be the case; not so in C.

此语句所做的全部工作就是将缓冲区 tempName 的内存地址复制到指针变量 tempNode-> itemName 中.这有两种错误.

All this statement does, is copy the memory address of buffer tempName into the pointer variable tempNode->itemName. This is wrong in two ways.

  1. 通过反复执行此操作,最终链表中的 all 个节点都引用了相同的字符串缓冲区.该缓冲区被重复覆盖;最后,剩下的就是从文件读取的最后一行.无论您访问哪个节点,都将始终看到相同的字符串.
  2. tempName 自动变量.一旦程序流离开函数 load ,就很可能会回收其内存.此后,链表继续引用该内存.这是导致未定义行为的主要错误.
  1. By repeatedly doing this, eventually all nodes in your linked list have a reference to the same string buffer. This buffer is overwritten repeatedly; at the end, all that is left is the last line read from file. Whatever node you access, you will always see that same string.
  2. tempName is an automatic variable. Its memory is likely to be reclaimed as soon as the program flow leaves function load. The linked list keeps on referring to that memory afterwards. This is a major bug that leads to undefined behavior.

解决方案是复制字符串.使用功能 strdup 可以很容易地做到这一点.只需替换以下代码:

The solution is to duplicate the string. This is easy to do with function strdup. Just replace this line of code:

tempNode->itemName = tempName;

作者:

tempNode->itemName = strdup(tempName);

这篇关于将单词保存到C中的链接列表的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆