使用while循环添加到链表结构不会';t保存数据(在C中)

使用while循环添加到链表结构不会';t保存数据(在C中),c,pointers,struct,while-loop,linked-list,C,Pointers,Struct,While Loop,Linked List,这是我的第一个问题,所以我希望我能很好地阐述它。我在StackOverflow上检查了其他一些类似的问题,但没有得到真正的答案。我有以下结构: struct process { int priority; char* path; char* parameters; struct process *next; }; 我正在读取文件中的每一行,并使用while循环将得到的字符串标记添加到struct链表中。以下是添加方法: struct process * add(int prio,char* p

这是我的第一个问题,所以我希望我能很好地阐述它。我在StackOverflow上检查了其他一些类似的问题,但没有得到真正的答案。我有以下结构:

struct process {
int priority;
char* path;
char* parameters;
struct process *next;
};
我正在读取文件中的每一行,并使用while循环将得到的字符串标记添加到struct链表中。以下是添加方法:

struct process * add(int prio,char* pat, char* par,  struct process *head) {
  struct process *new_node;
  new_node = ( struct process *) malloc(sizeof( struct process));
  new_node->priority = prio;
  new_node->path = pat;
  new_node->parameters = par;
  new_node->next= head;
  head = new_node;
  return head;
}
因此,主算法在while循环中使用fgets从文件中获取行:

while (fgets(line, sizeof(line), file))
然后我标记所有我需要的字符串,并使用add方法将它们添加到我的链接列表中。我将第一个字符串转换为int来表示类型

这是我的while循环和主算法:

        FILE *file = fopen(filename , "r");
    char line[124];
    // can be put outside and passed as argument.
    struct process *head = ( struct process *)malloc(sizeof(struct process));
    new_node->priority = prio;
    new_node->path = pat;
    new_node->parameters = par;
    new_node->next= head;
    char* priority,*path,*parameters;

    while (fgets(line, sizeof(line), file)) {
         priority=strtok(line," ");             
         // The fix here is the following :
         char *path_token = strtok(NULL, " ");
         path = malloc(strlen(path_token) + 1); 
         strcpy(path, path_token);
         char *par_token = strtok(NULL, "\n");
         parameters = malloc(strlen(par_token) + 1);
         strcpy(parameters, par_token);
         // End of edit Thanks to the answers bellow
         char* junk;
         int p = strtol(priority,&junk,10);
         printf("prio : %d  ",p);
         head = add(p, path, parameters,head);
         printf("\n");
         pront(head);
         printf("\n");
    }
    \\ free the mallocs
这里我们注意到,我在每一步都使用pront()方法打印我的链表。我在while循环之后也会这样做。以下是pront()的代码:

}

该方法将打印以下内容:

prio : 2  
2 , ./printchars , a 12 b 

prio : 15  
15 , ./printchars , c 23 d 
2 ,  ,  

prio : 7  
7 , ./printchars , e 34 f 
15 , /printchars ,  34 f 
2 , ./printchars , e 34 f 
它应该打印:

7 , ./printchars , e 34 f 
15 , ./printchars , c 23 d 
2 , ./printchars , a 12 b 
我确信问题来自while循环,因为在循环外使用adding方法然后打印时,我得到了有效的结果。但是一旦它进入循环,头链表就不能正确地存储值! 谢谢你的帮助


编辑:问题已经解决,问题是我在没有malloc的情况下错误地使用strtok和指向char的指针。吸取教训

问题在于以下代码

new_node->priority = prio;
new_node->path = pat;
new_node->parameters = par;

您的结构有一个字符指针,用于
路径
参数

您在这里所做的只是将结构中的指针分配给传递的函数中的指针。稍后当
pat
par
更改值或具有一些垃圾值时,结构元素也将具有垃圾值

您需要做的是为每个元素和数据分配内存

此外,@Ruks指出-

struct process *head = ( struct process *)malloc(sizeof(struct process)); 
head = NULL;
这是错误的。您正在丢失由
malloc
返回的指针。如果要确保链表最初为空,应初始化
头的所有元素

head-> priority = 0; 
head-> path = NULL;
head-> parameters = NULL;
head-> next = NULL;

问题在于下面的代码

new_node->priority = prio;
new_node->path = pat;
new_node->parameters = par;

您的结构有一个字符指针,用于
路径
参数

您在这里所做的只是将结构中的指针分配给传递的函数中的指针。稍后当
pat
par
更改值或具有一些垃圾值时,结构元素也将具有垃圾值

您需要做的是为每个元素和数据分配内存

此外,@Ruks指出-

struct process *head = ( struct process *)malloc(sizeof(struct process)); 
head = NULL;
这是错误的。您正在丢失由
malloc
返回的指针。如果要确保链表最初为空,应初始化
头的所有元素

head-> priority = 0; 
head-> path = NULL;
head-> parameters = NULL;
head-> next = NULL;

链接列表根本不存储这些值

问题不在于循环,而是——您使用它的方式不正确:它没有分配内存来保存它解析的令牌,而是使用一个内部静态缓冲区


因此,要保存这些值,必须为字符串分配内存(
path
parameters
),并使用
strcpy
将字符串复制到分配的内存中。 在释放列表项之前,请记住
释放
每个项字段

例如:

char *path_token = strtok(NULL, " ");
path = malloc(strlen(path_token) + 1); /* remember to allocate space for \0 terminator! */
strcpy(path, path_token));

链接列表根本不存储这些值

问题不在于循环,而是——您使用它的方式不正确:它没有分配内存来保存它解析的令牌,而是使用一个内部静态缓冲区


因此,要保存这些值,必须为字符串分配内存(
path
parameters
),并使用
strcpy
将字符串复制到分配的内存中。 在释放列表项之前,请记住
释放
每个项字段

例如:

char *path_token = strtok(NULL, " ");
path = malloc(strlen(path_token) + 1); /* remember to allocate space for \0 terminator! */
strcpy(path, path_token));

head=NULL。。。在
malloc()
-ed之后提供的算法中执行此操作。。。事实上,完全错了@Ruks我这样做是为了确保链接列表在流程开始时是空的。删除它不会改变任何东西,除了我有一个附加的空值对象(我不想要)。不!,您不应该使用
head=NULL为那!就是这样。。。您正试图通过向对象分配
NULL
来泄漏该对象!然而,这是错误的<代码>结构进程*head=(结构进程*)malloc(sizeof(结构进程))分配内存并将其地址存储在
头中
<代码>头=空覆盖
头部
。现在,刚刚分配的内存丢失了—这是内存泄漏。
path
参数
是指针。他们指的是什么?不同的
struct进程
中的
path
参数是否指向不同的位置?这些地方是什么?
head=NULL。。。在
malloc()
-ed之后提供的算法中执行此操作。。。事实上,完全错了@Ruks我这样做是为了确保链接列表在流程开始时是空的。删除它不会改变任何东西,除了我有一个附加的空值对象(我不想要)。不!,您不应该使用
head=NULL为那!就是这样。。。您正试图通过向对象分配
NULL
来泄漏该对象!然而,这是错误的<代码>结构进程*head=(结构进程*)malloc(sizeof(结构进程))分配内存并将其地址存储在
头中
<代码>头=空覆盖
头部
。现在,刚刚分配的内存丢失了—这是内存泄漏。
path
参数
是指针。他们指的是什么?不同的
struct进程
中的
path
参数是否指向不同的位置?这些地方是什么?我正在尝试一个解决方案,你在这里的建议!我5分钟后回来!我正试着用你的建议来解决问题