String read from file and string handling in C

You need to develop a program in pure C, which would read text from a file, split it into words and recorded them and the number of repetitions in a unidirectional list. The program sort of sketched out, but can't overcome the problem. The program works correctly only if the file has only one line.
If the file has only one line of "Star Wars is an American epic space opera film series created by George Lucas. Sixteen years after the release of the trilogy''s final film, the first in a new prequel trilogy of films was released.", the program gives this:
Word: Star Qty: 1
Word Wars Qty: 2
The word: is count: 2
The word: an Qty: 2
Word: American quantity: 2
Word: epic number: 2
Word: space number: 2
Word: opera Qty: 2
Word: film number: 2
Word: series Qty: 2
Word: created count: 2
Word: by Qty: 2
The word: George Qty: 2
Word: Lucas Qty: 2


If you do two lines, the result is something like this:
Word Wars Qty: 2
The word: is count: 2
Word: Qty: 1
Word: erican Qty: 1
Word: can Qty: 1
Word: space number: 2
Word: Qty: 1
Word: Qty: 1
Word: series Qty: 2
The word: s Qty: 1
Word: ed Qty: 1
The word orge Qty: 1
Word: e Qty: 1
Word: Qty: 1
The word: an Qty: 1
Word: American count: 1
Word: epic number: 1
Word: opera Qty: 1
Word: film number: 1
Word: created count: 1
Word: by Qty: 1
The word: George Qty: 1
Word: Lucas number: 1


The program starts to behave in abnormal ways. I do not understand what the error is. Here is the listing:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct list_item 
{ 
 char *item;
 int count;
 struct list_item *next;
} ITEM_LIST;

int check(ITEM_LIST *l, char *c)
{
 while (l != NULL)
{
 if (strcmp(c,l->item) == 0)
{
l->count++;
 return 0;
}
 else l=l->next;
}
 return 1;
}

void show(ITEM_LIST *l)
{
 if (l == NULL)
return;
 printf("Word: %s\t number: %d\n", l->item, l->count);
show(l->next);
}

int main (void)
{
 char buf[4096];
 char *ptr;
 FILE *f = fopen("file1","r");
 if (f == NULL)
{
 printf("Error. I can't find file.");
 return 0;
}

 ITEM_LIST *list;
 ITEM_LIST *beg = NULL;
 ITEM_LIST *end = NULL;

while(!feof(f))
{
 if (fgets(buf,sizeof(buf),f))
{
printf("%s",buf);
 for(ptr = strtok(buf," ,.:;!?\n\t"); ptr != NULL; ptr = strtok(NULL," ,.:;!?\n\t"))
{
 list=(ITEM_LIST *)malloc(sizeof(ITEM_LIST));
 if (check(beg, ptr))
{
 list->item = ptr;
 list->count = 1;
 if (beg == NULL && end == NULL) 
 beg = list;
else
 end->next = list;
 end = list;
 end->next = NULL;
}
else
free(list);
}
}
}

fclose(f);
show(beg);
 return 0;
}</stdlib.h></string.h></stdio.h>
October 8th 19 at 02:49
1 answer
October 8th 19 at 02:51
Solution
Are you sure that strtok will always create a new line without overwriting the old one, when store a pointer to the token in your list?

Replace
list->item = ptr;<br>
on
list->item = (char *)malloc(strlen(ptr) + 1);<br> strcpy(ptr, list->item);<br>
Brrr... of Course:
strcpy(list->item, ptr); - eliezer.Bahringer commented on October 8th 19 at 02:54

Find more questions by tags CBooks