C 从文件中逐个读取字符串并将其添加到链接列表中
我试图从文本文件中逐个读取字符串,并将其添加到链接列表中。节点包含字符串本身以及该字符串在文件中的出现次数。因此,每个字符串只会被添加到链表中一次,如果链表中已有该字符串,则节点中的int num变量应增加1禁止使用数组。C 从文件中逐个读取字符串并将其添加到链接列表中,c,string,file,text,C,String,File,Text,我试图从文本文件中逐个读取字符串,并将其添加到链接列表中。节点包含字符串本身以及该字符串在文件中的出现次数。因此,每个字符串只会被添加到链表中一次,如果链表中已有该字符串,则节点中的int num变量应增加1禁止使用数组。 typedef struct node { char *word; int num; struct node *next; } node; node* addToHead(node *head, char word[]) { if(Conta
typedef struct node
{
char *word;
int num;
struct node *next;
} node;
node* addToHead(node *head, char word[])
{
if(Contains(head, word) == 0)
{
node *tmp = (node*)malloc(sizeof(node));
tmp->word = (char)malloc((sizeof(char)* strlen(word) + sizeof(char)));
tmp->word = word;
tmp->num = 1;
if(head == NULL)
{
tmp->next = NULL;
head = tmp;
}
}
return head;
}
node* add(node *head, char word[])
{
if(Contains(head, word) == 0)
{
node *iter = head;
node *tmp = (node*)malloc(sizeof(node));
tmp->word = (char)malloc((sizeof(char)* strlen(word) + sizeof(char)));
tmp->word = word;
tmp->num = 1;
if(head != NULL)
{
while(iter->next != NULL)
iter = iter->next;
iter->next = tmp;
tmp->next = NULL;
return head;
}
else if(head == NULL)
{
head = addToHead(head, word);
return head;
}
}
return head;
}
int Contains(node *head, char word[])
{
node *iter = head;
while(iter!= NULL)
{
if(strcmp(iter->word, word) == 0)
{
iter->num++;
return 1;
}
iter = iter->next;
}
return 0;
}
void printList(node *head)
{
node *iter = head;
while(iter!=NULL)
{
printf("word: %s || number of word: %d\n", iter->word, iter->num);
iter=iter->next;
}
}
int main()
{
node *head=NULL;
FILE* file= fopen("text.txt", "r");
char word[500];
for(int i = 0; fscanf(file, "%s", word) != EOF; i++)
{
head = add(head, word);
printList(head);
}
printList(head);
return 0;
}
在这段代码中,每次向链表添加新字符串时,我都会重写链表。据我所知,它不会生成新节点,而是在先前添加的单词上重写单词。COMMA和dots不是问题。我写了3次相同的Lorem Ipsum段落。输出如下所示:
从文件中读取单词时,如何为每个单词创建单个节点?使用6个字符串的固定大小数组进行测试,您的代码工作正常,打印输出如预期:
int main()
{
node *head=NULL;
char * word[6] = {"Alpha", "Beta", "Alpha", "Teta", "Alpha", "Beta"};
for(int i = 0; i<6; i++)
{
head = add(head, word[i]);
}
printList(head);
return 0;
}
因此,正如在注释中所解释的,问题似乎在于您分配这些字符串和/或从文件中读取它们的方式。如上所述,您的代码有几个问题:
tmp->word=(char)malloc((sizeof(char)*strlen(word)+sizeof(char))代码>。Malloc返回一个指向已分配地址的指针,因此您应该写入:
tmp->word=(char*)malloc((sizeof(char)*strlen(word)+sizeof(char))代码>
tmp->word=word
,即使您分配了一个新节点,它的单词字段也会指向当前单词。因此,当你在循环中阅读一个单词时,你是在意外地改变head->word
。所以你应该这样做strcpy(tmp->word,word)
#include<stdio.h>
typedef struct node
{
char *word;
int num;
struct node *next;
} node;
node* addToHead(node *head, char word[])
{
if(Contains(head, word) == 0)
{
node *tmp = (node*)malloc(sizeof(node));
//tmp->word = (char)malloc((sizeof(char)* strlen(word) + sizeof(char)));
//tmp->word = word;
tmp->word = (char *)malloc((sizeof(char)* strlen(word) + sizeof(char)));
strcpy(tmp->word, word);
tmp->num = 1;
if(head == NULL)
{
tmp->next = NULL;
head = tmp;
}
}
return head;
}
node* add(node *head, char word[])
{
if(Contains(head, word) == 0)
{
node *iter = head;
node *tmp = (node*)malloc(sizeof(node));
//tmp->word = (char)malloc((sizeof(char)* strlen(word) + sizeof(char)));
//tmp->word = word;
tmp->word = (char *)malloc((sizeof(char)* strlen(word) + sizeof(char)));
strcpy(tmp->word, word);
tmp->num = 1;
if(head != NULL)
{
while(iter->next != NULL)
iter = iter->next;
iter->next = tmp;
tmp->next = NULL;
return head;
}
else if(head == NULL)
{
head = addToHead(head, word);
return head;
}
}
return head;
}
int Contains(node *head, char word[])
{
node *iter = head;
while(iter!= NULL)
{
if(strcmp(iter->word, word) == 0)
{
iter->num++;
return 1;
}
iter = iter->next;
}
return 0;
}
void printList(node *head)
{
node *iter = head;
while(iter!=NULL)
{
printf("word: %s || number of word: %d\n", iter->word, iter->num);
iter=iter->next;
}
}
int main()
{
node *head=NULL;
FILE* file= fopen("text.txt", "r");
char word[500];
for(int i = 0; fscanf(file, "%s", word) != EOF; i++)
{
head = add(head, word);
printList(head);
}
printList(head);
return 0;
}
#包括
类型定义结构节点
{
字符*字;
int-num;
结构节点*下一步;
}节点;
node*addToHead(node*head,char-word[])
{
if(包含(头、字)==0)
{
node*tmp=(node*)malloc(sizeof(node));
//tmp->word=(char)malloc((sizeof(char)*strlen(word)+sizeof(char));
//tmp->word=word;
tmp->word=(char*)malloc((sizeof(char)*strlen(word)+sizeof(char));
strcpy(tmp->word,word);
tmp->num=1;
if(head==NULL)
{
tmp->next=NULL;
水头=tmp;
}
}
回流头;
}
节点*添加(节点*头,字符字[])
{
if(包含(头、字)==0)
{
节点*iter=头部;
node*tmp=(node*)malloc(sizeof(node));
//tmp->word=(char)malloc((sizeof(char)*strlen(word)+sizeof(char));
//tmp->word=word;
tmp->word=(char*)malloc((sizeof(char)*strlen(word)+sizeof(char));
strcpy(tmp->word,word);
tmp->num=1;
if(head!=NULL)
{
while(iter->next!=NULL)
iter=iter->next;
iter->next=tmp;
tmp->next=NULL;
回流头;
}
else if(head==NULL)
{
head=addToHead(head,word);
回流头;
}
}
回流头;
}
int包含(节点*头,字符字[])
{
节点*iter=头部;
while(iter!=NULL)
{
if(strcmp(iter->word,word)==0)
{
iter->num++;
返回1;
}
iter=iter->next;
}
返回0;
}
无效打印列表(节点*头)
{
节点*iter=头部;
while(iter!=NULL)
{
printf(“单词:%s | |单词数:%d\n”,iter->word,iter->num);
iter=iter->next;
}
}
int main()
{
node*head=NULL;
FILE*FILE=fopen(“text.txt”、“r”);
字符字[500];
对于(int i=0;fscanf(文件“%s”,word)!=EOF;i++)
{
head=添加(head,word);
印刷品清单(标题);
}
印刷品清单(标题);
返回0;
}
Hm。您的问题在于分配字符串的位置。使用malloc
分配内存,在下一条指令中,将保存分配内存的指针分配给word
。这意味着(a)您不再有权访问分配的内存,这是内存泄漏;(b)所有数据都具有相同的数据,只要行缓冲区中写入的数据仍然“活动”。C是非常明确的,在为字符串长度和终止符分配足够的字节后,您应该strcpy
将字符串放入该内存中。您可能听说过在C中,您不应该强制转换malloc
的结果。C++需要演员,所以有些人还是这样做。但您肯定不想做的是将指针投射到char
——您将尝试将64位值存储在8位中,这会导致灾难。丢失该演员阵容,同时将sizeof(char)
也替换为1。你会很好,有一个漂亮的,简短的malloc(strlen(word)+1)代码>天哪,非常感谢。strcpy()解决了我的所有问题。禁止使用数组。那么,存储字符串会有问题。字符串只不过是一个字符的数组,其中最后一个字符的值为'\0'
@AndrewHenle分配内存并在其中存储数据(形成字符串)并不真正构成数组。OTOH,printf(“单词数:%s | |单词数:%d\n”
确实使用了数组。在任何情况下,“使用数组是禁止的。”是对强调错误想法的弱赋值的反映。
#include<stdio.h>
typedef struct node
{
char *word;
int num;
struct node *next;
} node;
node* addToHead(node *head, char word[])
{
if(Contains(head, word) == 0)
{
node *tmp = (node*)malloc(sizeof(node));
//tmp->word = (char)malloc((sizeof(char)* strlen(word) + sizeof(char)));
//tmp->word = word;
tmp->word = (char *)malloc((sizeof(char)* strlen(word) + sizeof(char)));
strcpy(tmp->word, word);
tmp->num = 1;
if(head == NULL)
{
tmp->next = NULL;
head = tmp;
}
}
return head;
}
node* add(node *head, char word[])
{
if(Contains(head, word) == 0)
{
node *iter = head;
node *tmp = (node*)malloc(sizeof(node));
//tmp->word = (char)malloc((sizeof(char)* strlen(word) + sizeof(char)));
//tmp->word = word;
tmp->word = (char *)malloc((sizeof(char)* strlen(word) + sizeof(char)));
strcpy(tmp->word, word);
tmp->num = 1;
if(head != NULL)
{
while(iter->next != NULL)
iter = iter->next;
iter->next = tmp;
tmp->next = NULL;
return head;
}
else if(head == NULL)
{
head = addToHead(head, word);
return head;
}
}
return head;
}
int Contains(node *head, char word[])
{
node *iter = head;
while(iter!= NULL)
{
if(strcmp(iter->word, word) == 0)
{
iter->num++;
return 1;
}
iter = iter->next;
}
return 0;
}
void printList(node *head)
{
node *iter = head;
while(iter!=NULL)
{
printf("word: %s || number of word: %d\n", iter->word, iter->num);
iter=iter->next;
}
}
int main()
{
node *head=NULL;
FILE* file= fopen("text.txt", "r");
char word[500];
for(int i = 0; fscanf(file, "%s", word) != EOF; i++)
{
head = add(head, word);
printList(head);
}
printList(head);
return 0;
}