使用while循环添加到链表结构不会保存数据(IN C)

时间:2018-11-22 06:23:35

标签: c pointers struct while-loop linked-list

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

struct process {
int priority;
char* path;
char* parameters;
struct process *next;
};

我正在从文件中读取每一行,并使用while循环添加在结构链接列表中获得的字符串标记。这是添加方法:

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()的代码:

void pront(struct process *head) {
struct process *current_node = head;
while ( current_node != NULL) {
    printf("%d , %s , %s ", current_node->priority, current_node->path, current_node->parameters);
    printf("\n");
    current_node = current_node->next;
}

}

该方法显示废话:

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循环,因为在循环外使用添加方法然后打印时,我得到了有效的结果。但是,一旦进入循环,Head链接列表就无法正确存储值! 感谢您的帮助

编辑:问题已解决,问题是我在没有malloc的情况下对strtok和char指针的使用完全错误。学过的知识 !

2 个答案:

答案 0 :(得分:2)

问题包含以下代码。

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

您的结构具有pathparameters的字符指针

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

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

@Ruks指出-

struct process *head = ( struct process *)malloc(sizeof(struct process)); 
head = NULL;

是错误的。您正在失去malloc返回的指针。如果要确保链接列表最初为空,则应初始化head的所有元素。

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

答案 1 :(得分:1)

您的链接列表根本不存储值。

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

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

示例:

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