以下程序接收ins "name_to_insert" birthdate
形式的输入字符串,并应将此信息插入双向链接列表中。每次插入后都会显示列表的内容以及元素数量。正确显示元素数量,但不是名称和出生日期,而是显示 2686707 n次(n =列表中的元素数)。
我怀疑我的打印功能 printList()有问题,但我无法弄清楚是什么。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DLList.h"
typedef struct dataStructure
{
int birthday;
char *name;
} dataStructure;
int main()
{
ListT *l=createList();
char op[4], nameTemp[30], *name, s[50];
int date;
while (scanf("%[^\n]%*c", s)==1)
{
sscanf(s, "%s", op);
if (strcmp(op, "ins")==0)
{
sscanf(s, "%*s %[^0-9]%d", nameTemp, &date);
name=nameTemp+1; // Remove opening quotation mark
name[strlen(name)-2]='\0'; // Remove closing quotation mark
NodeT *p=createNode();
p->data=(dataStructure*)malloc(sizeof(dataStructure));
((dataStructure*)p->data)->birthday=date;
((dataStructure*)p->data)->name=name;
insertLastNode(l, p);
printf("List length: %d\n", l->length);
printList(l);
}
}
return 0;
}
void printList(ListT *l)
{
NodeT *p=l->first;
while (p)
{
printf("%d %s\n", (((dataStructure*)p->data)->birthday, (dataStructure*)p->data)->name);
p=p->next;
}
printf("--\n");
}
DLList.h的内容:
#include <stdio.h>
#include <stdlib.h>
typedef struct nodetype
{
struct nodetype *prev, *next;
void *data;
} NodeT;
typedef struct
{
int length;
NodeT *first, *last;
} ListT;
NodeT *createNode();
ListT *createList();
void insertLastNode(ListT *l, NodeT *p);
DLList.c 的内容:
#include "DLList.h"
NodeT *createNode()
{
NodeT *p=(NodeT*)malloc(sizeof(NodeT));
p->next=p->prev=NULL;
return p;
}
ListT *createList()
{
ListT *l=(ListT*)malloc(sizeof(ListT));
l->first=l->last=NULL;
l->length=0;
return l;
}
void insertLastNode(ListT *l, NodeT *p)
{
if (l->first==NULL)
{
l->first=l->last=p;
p->prev=p->next=NULL;
l->length++;
}
else
{
p->prev=l->last;
p->next=NULL;
l->last->next=p;
l->last=p;
l->length++;
}
}
答案 0 :(得分:1)
在您的程序中,您将指针指向name
,如下所示:
((dataStructure*)p->data)->name=name;
此名称源自sscanf
,如下所示:
sscanf(s, "%*s %[^0-9]%d", nameTemp, &date);
name=nameTemp+1; // Remove opening quotation mark
name[strlen(name)-2]='\0'; // Remove closing quotation mark
这意味着对于循环的每次运行,您将读入相同的nameTemp
或name
数组并将其存储到链接列表中。对于循环的每次运行,您可能必须分配一个单独的空间来存储name
并将其分配给您的节点。
编辑1:
创建新节点时,还存在一个类型转换问题。 p->data
属于void *
类型,我相信在代码中,新分配的内存类型为dataStructure *
,如下所示
p->data=(dataStructure*)malloc(sizeof(dataStructure));
您还可以更改数据结构定义,如下所示
typedef struct dataStructure
{
int birthday;
char name[64]; // Change from pointer to an array
} dataStructure;
并修改循环中的逻辑以复制名称,如下所示:
p->data=(dataStructure*)malloc(sizeof(dataStructure));
((dataStructure*)p->data)->birthday=date;
strcpy(((dataStructure*)p->data)->name, name); // Modified from pointer assignment to strcpy
答案 1 :(得分:1)
代码中有两个错误。
<强>首先:强> 而不是
((dataStructure*)p->data)->name=name;
DO
((dataStructure*)p->data)->name = (char*)malloc(strlen(name)+1);
strcpy(((dataStructure*)p->data)->name, name);
避免内存泄漏。
<强>第二强> 在printList函数中,括号出现错误。请按以下步骤操作:
printf("%d %s\n", ((dataStructure*)p->data)->birthday, ((dataStructure*)p->data)->name);
其他一切都有效。这是测试程序时得到的输出。
答案 2 :(得分:0)
在调试器中运行此命令以确切了解您的函数正在执行的操作。例如,如果您从Unix命令行运行,请使用-g
标志进行编译,然后在gdb
中运行。在功能开头设置断点,这会给您带来麻烦。谷歌有点像“gdb备忘单”的细节,很容易。