为什么我的链表只打印最后一个条目?
Why is my linked list only printing last entry?
我正在尝试从文件中读取特定行并将其添加到链表中,然后打印出来。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct list {
int uid;
char* uname;
struct list* next;
}node;
void push(node ** head, int uid ,char* uname) {
node * new_node;
new_node = malloc(sizeof(node));
new_node->uid = uid ;
new_node->uname=uname;;
new_node->next = *head;
*head = new_node;
}
void print_list(node *head) {
node * current = head;
while (current != NULL) {
printf("%u:%s\n", current->uid,current->uname);
current = current->next;
}
}
int main(int argc, char **argv){
node *current=NULL;
FILE *fp=fopen(argv[1],"r" );
if (fp==NULL){
perror("Failed to open file");
exit(EXIT_FAILURE);
}
char s[1024];
const char token[2]=":";
char *stoken;
while(!feof(fp)){
int count=0;
int tempint;
char* tempchar=malloc(sizeof(char));
fgets(s, 1024, fp);
stoken = strtok(s,token);
current=malloc(sizeof(node));
while(stoken != NULL){
if (count==0){
tempchar=stoken;
}
if (count==2){
sscanf(stoken,"%d",&tempint);
}
count++;
stoken=strtok(NULL,token);
}
push(¤t,tempint,tempchar);
}
fclose(fp);
print_list(current);
}
我的问题是当 print_list
是 运行 时,唯一打印的是最后一个条目。
对于此输入:
hello:asd:123:foo:ar
hi:proto:124:oo:br
hey:qwe:321:fo:bar
唯一打印出来的是
321:hey
是我推错了还是我print_list?
因为你总是在push()
函数中覆盖head
,你应该先把它设为NULL
,然后第一次检查是否是NULL
并赋值给它是第一个节点,然后不要对它重新评估,你的程序也因此发生内存泄漏。
您还 malloc()
将节点置于函数外部,然后再次置于函数内部,这会导致另一次内存泄漏。
您还应该检查 malloc()
returns NULL
是否指示错误,例如系统内存不足时,取消引用 NULL
指针是未定义的行为.
最后一点,在访问目标变量之前,您 必须 检查 scanf()
的 return 值,否则会再次导致未定义的行为。
问题在于您处理 strtok
结果的方式:您将其值直接设置到节点中,而不是复制它。
添加节点时复制name
:
void push(node ** head, int uid ,char* uname) {
node * new_node;
new_node = malloc(sizeof(node));
new_node->uid = uid;
new_node->uname=malloc(strlen(uname)+1);
strcpy(new_node->uname, uname);
new_node->next = *head;
*head = new_node;
}
您还应该查看在 main
函数中使用 tempchar
的方式。你为它分配了一个 space 用于单个字符,它被 strtok
的结果覆盖,泄漏了 malloc
-ed 内存。
修改如下
char* tempchar;//=malloc(sizeof(char));
fgets(s, 1024, fp);
stoken = strtok(s,token);
//current=malloc(sizeof(node));//don't update like this
while(stoken != NULL){
if (count==0){
tempchar=strdup(stoken);//malloc and strcpy
我正在尝试从文件中读取特定行并将其添加到链表中,然后打印出来。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct list {
int uid;
char* uname;
struct list* next;
}node;
void push(node ** head, int uid ,char* uname) {
node * new_node;
new_node = malloc(sizeof(node));
new_node->uid = uid ;
new_node->uname=uname;;
new_node->next = *head;
*head = new_node;
}
void print_list(node *head) {
node * current = head;
while (current != NULL) {
printf("%u:%s\n", current->uid,current->uname);
current = current->next;
}
}
int main(int argc, char **argv){
node *current=NULL;
FILE *fp=fopen(argv[1],"r" );
if (fp==NULL){
perror("Failed to open file");
exit(EXIT_FAILURE);
}
char s[1024];
const char token[2]=":";
char *stoken;
while(!feof(fp)){
int count=0;
int tempint;
char* tempchar=malloc(sizeof(char));
fgets(s, 1024, fp);
stoken = strtok(s,token);
current=malloc(sizeof(node));
while(stoken != NULL){
if (count==0){
tempchar=stoken;
}
if (count==2){
sscanf(stoken,"%d",&tempint);
}
count++;
stoken=strtok(NULL,token);
}
push(¤t,tempint,tempchar);
}
fclose(fp);
print_list(current);
}
我的问题是当 print_list
是 运行 时,唯一打印的是最后一个条目。
对于此输入:
hello:asd:123:foo:ar
hi:proto:124:oo:br
hey:qwe:321:fo:bar
唯一打印出来的是
321:hey
是我推错了还是我print_list?
因为你总是在push()
函数中覆盖head
,你应该先把它设为NULL
,然后第一次检查是否是NULL
并赋值给它是第一个节点,然后不要对它重新评估,你的程序也因此发生内存泄漏。
您还 malloc()
将节点置于函数外部,然后再次置于函数内部,这会导致另一次内存泄漏。
您还应该检查 malloc()
returns NULL
是否指示错误,例如系统内存不足时,取消引用 NULL
指针是未定义的行为.
最后一点,在访问目标变量之前,您 必须 检查 scanf()
的 return 值,否则会再次导致未定义的行为。
问题在于您处理 strtok
结果的方式:您将其值直接设置到节点中,而不是复制它。
添加节点时复制name
:
void push(node ** head, int uid ,char* uname) {
node * new_node;
new_node = malloc(sizeof(node));
new_node->uid = uid;
new_node->uname=malloc(strlen(uname)+1);
strcpy(new_node->uname, uname);
new_node->next = *head;
*head = new_node;
}
您还应该查看在 main
函数中使用 tempchar
的方式。你为它分配了一个 space 用于单个字符,它被 strtok
的结果覆盖,泄漏了 malloc
-ed 内存。
修改如下
char* tempchar;//=malloc(sizeof(char));
fgets(s, 1024, fp);
stoken = strtok(s,token);
//current=malloc(sizeof(node));//don't update like this
while(stoken != NULL){
if (count==0){
tempchar=strdup(stoken);//malloc and strcpy