我是 C 语言的初学者,所以我知道我的代码可能看起来很糟糕。我想做的就是创建一个链表,其中包含一个包含字符数组和频率的
int
的结构。它从测试文件中读取行并简单地打印出该文件。它正确读取文件,第一次迭代链表并正确打印出来。然而,在链表的第二次迭代中,它打印出正确的行数和正确的整数,但单词被符号替换。我到处都找过了,我只需要一些帮助。这是我的代码。
#include <stdio.h>
#include <stdlib.h>
#define Word_MAX_LENGTH 255
struct WordFreq
{
char word[Word_MAX_LENGTH];
int frequency;
struct WordFreq *next;
} WordFreq;
struct WordFreq *head = NULL;
void insert(struct WordFreq *newNode)
{
if (head == NULL)
{
head = newNode;
newNode->next = NULL;
return;
}
struct WordFreq *current = head;
while (current->next != NULL)
{
current = current->next;
}
current->next = newNode;
newNode->next = NULL;
}
void main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Please run as %s [filename]\n", argv[0]);
return;
}
FILE *f;
f = fopen(argv[1], "r");
if (f == NULL)
{
printf("File (%s) does not exist\n", argv[1]);
return;
}
struct WordFreq *line = malloc(sizeof(struct WordFreq));
if (line == NULL)
{
printf("Cannot do dynamic memory managment\n");
return;
}
printf("File content in %s:\n", argv[1]);
while (fscanf(f, "%s %d", line->word, &(line->frequency)) != EOF)
{
printf("%s %d\n", line->word, line->frequency);
insert(line);
line = malloc(sizeof(struct WordFreq));
if (line == NULL)
{
printf("Cannot do dynamic memory management");
return;
}
}
fclose(f);
// To keep head intact for sorting portion
struct WordFreq *current = head;
printf("\nContent of linked list:\n");
while (current != NULL)
{
printf("%s %d\n", current->word, current->frequency);
struct WordFreq *temp = current;
current = current->next;
free(temp);
}
printf("\n\n\n");
current = head;
while (current != NULL)
{
printf("%s %d\n", current->word, current->frequency);
current = current->next;
}
free(current);
free(line);
}
非常感谢任何帮助。很遗憾我已经编程了一段时间了,但我想学习 C,因为我想了解程序为何这样做的来龙去脉,以帮助未来的努力。
您在第一次迭代期间释放了链表,因此第二次迭代具有未定义的行为,因为
head
已成为无效指针并且列表节点的内存内容已更改。从它们中读取具有未定义的行为,任何事情都可能发生,包括程序因无效的内存访问或随机输出而停止,如您所观察到的。
您应该编写函数:一个用于打印列表内容,另一个用于释放列表。组合这些操作会造成混乱并导致诸如此类的逻辑错误。