Thread: What is causing this?

  1. #1
    Registered User
    Join Date
    Jan 2005
    Posts
    204

    What is causing this?

    I wrote this program to read two files, separate the lines read into words and write the words, the number of times they were found on both files and the number of the where they came from. For some reason, my program is skipping the last word. Can someone help me find the problem? Thanks.

    text1.txt
    Code:
    look at the stars
    text2.txt
    Code:
    look how they shine for you
    out.txt
    Code:
    look 	 2 	 1
    at 	 1 	 1
    the 	 1 	 1
    stars 	 1 	 1
    how 	 1 	 2
    they 	 1 	 2
    shine 	 1 	 2
    for 	 1 	 2
    Here's the program
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define FILES 2
    
    int add_word(const char *, const int);
    int word_exists(const char *);
    void write_list(void);
    
    struct Word {
    	char word[30];
    	int occurrences;
    	int document;
    };
    
    struct Node {
    	struct Word word;
    	struct Node *next;
    };
    
    struct Node *first_node = NULL;
    
    int main(void)
    {
    	int i;
    	FILE *in;
    	char line[BUFSIZ];
    	char *word = NULL;
    	char list[FILES][11] = {"text1.txt", "text2.txt"};
    
    	for(i = 0; i < FILES; ++i) {
    		in = fopen(list[i], "r");
    		if(in == NULL){
    			printf("unknown file: %s\n", list[i]);
    			return 0;
    		}
    
    		while(fgets(line, sizeof(line), in) != NULL) {
    			if(strchr(line, '\n') != NULL)
    				line[strlen(line) - 1] = '\0';
    
    			word = strtok(line, " ");
    			while(word != NULL) {
    				add_word(word, i + 1); /* i + 1 is the document's number */
    				word = strtok(NULL, " ");
    			}
    		}
    
    		fclose(in);
    	}
    
    	write_list();
    
    	return 0;
    }
    
    int add_word(const char *word2_add, const int doc_number)
    {
    	struct Node *new_node;
    	struct Node *walker;
    
    	if(word_exists(word2_add) == 1)
    		return 0;
    
    	else {
    		new_node = (struct Node *)malloc(1 * sizeof(*new_node));
    
    		if(new_node == NULL){
    			printf("error allocating memory\n");
    			exit(1);
    		}
    
    		new_node->next = NULL;
    		strcpy(new_node->word.word, word2_add);
    		new_node->word.occurrences = 0;
    		new_node->word.occurrences++;
    		new_node->word.document = doc_number;
    
    		if(first_node == NULL)
    			first_node = new_node;
    
    		else {
    			walker = first_node;
    
    			while(walker->next != NULL)
    				walker = walker->next;
    			
    			walker->next = new_node;
    		}
    	}
    
    	return 0;
    }
    
    
    int word_exists(const char *word)
    {
    
    	struct Node *walker;
    	walker = first_node;
    
    	if(walker == NULL)
    		return 0;
    
    	else {
    		while(walker->next != NULL) {
    			if(strcmp(word, walker->word.word) == 0) {
    				walker->word.occurrences++;
    				return 1;
    			}
    
    			else
    				walker = walker->next;
    		}
    	}
    	
    	return 0;
    }
    
    void write_list(void)
    {
    	FILE *out;
    	struct Node *walker;
    	
    	walker = first_node;
    	out = fopen("out.txt", "w");
    
    	if(out == NULL) {
    		printf("could not create out.txt\n");
    		getchar();
    		exit(1);
    	}
    
    	while(walker->next != NULL) {
    		fprintf(out, "%s \t %d \t %d\n", walker->word.word, 
    			    walker->word.occurrences, walker->word.document);
    		walker = walker->next;
    	}
    
    	fclose(out);
    }
    Thanks a lot.

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    It's being added to the list, but it's not being printed. You could twiddle the loop like this:
    Code:
       for ( ;; )
       {
          fprintf(out, "%s \t %d \t %d\n", walker->word.word,
                  walker->word.occurrences, walker->word.document);
          if ( walker->next == NULL )
          {
             break;
          }
          walker = walker->next;
       }
    This prints the last one, then checks for NULL.

    I'd recommend looking into it more than I did for a better solution than this, but that may be the spot to start looking.
    Last edited by Dave_Sinkula; 05-26-2005 at 09:52 AM. Reason: ::reads following response:: ::smacks forehead::
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Code:
    	while(walker->next != NULL) {
    Try changing that to:
    Code:
    	while(walker != NULL) {
    If you understand what you're doing, you're not learning anything.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    204
    Nice. Thanks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. strtok is causing segmentation fault
    By yougene in forum C Programming
    Replies: 11
    Last Post: 03-08-2008, 10:32 AM
  2. A libdc1394 library function is causing a segmentation fault
    By Phanixis in forum Linux Programming
    Replies: 7
    Last Post: 10-16-2007, 12:44 PM
  3. strlen causing my program to freeze
    By Beowolf in forum C Programming
    Replies: 2
    Last Post: 09-11-2007, 04:09 PM
  4. Class member using a global variable, causing problems.
    By RealityFusion in forum C++ Programming
    Replies: 1
    Last Post: 09-11-2005, 11:27 PM
  5. what is causing this seemingly simple app to crash?
    By Shadow12345 in forum C++ Programming
    Replies: 6
    Last Post: 12-06-2002, 08:36 PM