【问题标题】:Issue with saving words to linked lists in C将单词保存到 C 中的链表的问题
【发布时间】:2016-03-05 20:18:05
【问题描述】:
#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 是一个简单的记事本文件,包含以下信息。

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

在保存功能之后,所有数字都通过了,但以下是控制台打印出来的内容以及在 California.txt 文件中重写的内容。

{°@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(在加载中找到的字符串)变成一个指针并像这样运行函数,但随后控制台打印出来并保存到 california 文件。

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

我真的在这里遇到了死胡同,我无法弄清楚如何解决这个问题,任何建议都会有所帮助。如果它工作正常,它应该将以下内容打印到控制台。

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

【问题讨论】:

标签: c pointers struct linked-list nodes


【解决方案1】:

我认为你的问题是你保存的是同一个指针。

看:

typedef struct node
{
 int priorityc;
 char *itemName; <= here you have pointer
 struct node *next;
} node;`

还有,

tempNode-&gt;itemName = tempName; &lt;= and here you get always the same pointer, not the value

尝试使用:strcpy(tempNode-&gt;itemName, tempName); 看看它是否有效。 ;)

【讨论】:

  • 除非你将内存分配给tempNode-&gt;itemName,否则它不会工作。
【解决方案2】:

您的node 通过指针存储名称

char *itemName;

但是在load() 中,您不会为每个节点分配内存。您只需将其指向tempName,这是一个局部变量,因此在函数的末尾您会得到一个悬空指针。你需要为每个itemName分配内存,然后使用strcpy之类的函数将结果复制到其中。

另一种选择是使用固定长度数组,例如

char itemName[80];

然后strncpy 进入它。

【讨论】:

    【解决方案3】:

    您可能会误以为您的任务声明:

    tempNode->itemName = tempName;
    

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

    这条语句所做的只是将缓冲区tempName的内存地址复制到指针变量tempNode-&gt;itemName中。这在两个方面是错误的。

    1. 通过反复执行此操作,您的链表中的所有 节点最终都会引用相同的字符串缓冲区。该缓冲区被反复覆盖;最后,剩下的就是从文件中读取的最后一行。无论您访问哪个节点,您都会看到相同的字符串。
    2. tempNameautomatic variable。一旦程序流离开函数load,它的内存很可能会被回收。之后,链表继续引用该内存。这是一个导致未定义行为的主要错误。

    解决方案是复制字符串。使用函数strdup 很容易做到这一点。只需替换这行代码:

    tempNode->itemName = tempName;
    

    作者:

    tempNode->itemName = strdup(tempName);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-08
      相关资源
      最近更新 更多