这是我的第一个问题,所以我希望我能很好地表述它。我在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的指针。吸取教训!
问题是以下代码。
new_node->priority = prio;
new_node->path = pat;
new_node->parameters = par;
您的结构有一个用于path
和parameters
的字符指针
您在这里所做的只是将结构中的指针分配给传递的函数中的指针。稍后,当pat
或par
更改值或具有一些垃圾值时,结构元素也将具有垃圾值。
您需要做的是为每个元素分配内存,并将数据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;
您的链表根本不存储值。
问题不在于循环,而是strtok
——您使用它不正确:它没有分配内存来保存它解析的令牌,而是使用单个内部静态缓冲区。
因此,要保存这些值,必须为字符串(path
和parameters
(分配内存,并使用strcpy
将字符串复制到分配的内存中。在释放列表项之前,请记住free
每个项字段!
示例:
char *path_token = strtok(NULL, " ");
path = malloc(strlen(path_token) + 1); /* remember to allocate space for terminator! */
strcpy(path, path_token));