Linked Lists

Discussion in 'C Programming' started by Foodbank, Oct 2, 2005.

  1. Foodbank

    Foodbank Guest

    Hi,

    I have to write a program that will use linked lists to print the
    number of unique words, total words, and the most frequent word from a
    text file. I've gotten a decent amount of it done except for the
    linked lists. I did not paste my code that tells the machine what a
    word is, it works fine and it'll be easier to read that way without it.
    Below is the code:

    //****code from here to next section is good, I don't need help
    there****//
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    struct list_elem {
    char *word;
    int count;
    struct list_elem *next;
    };

    struct list_elem *head; /* the head pointer is initially NULL */

    int get_word(char *);
    void add_to_list(char *);
    void list_walk(void);

    int unique_words, total_words;
    struct list_elem *most_frequent_elem;

    main() {
    char word_buff[100];
    while(get_word(word_buff))
    add_to_list(word_buff);
    list_walk();
    printf("there are %d unique words out of %d total words\n",
    unique_words, total_words);
    printf("the most frequent word is <%s> which used %d times\n",
    most_frequent_elem->word, most_frequent_elem->count);
    }
    //**************************
    //***********help here and below
    void add_to_list(char *word_buff) {
    /* *CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS
    /* ** CODE TO MAKE NEW ELEMENTS FOR BRAND NEW WORDS


    void list_walk() {
    /* ****** CODE TO WALK THE LIST AND GATHER THE STATS
    }

    Any help is greatly appreciated.

    Thanks,
    James
    Foodbank, Oct 2, 2005
    #1
    1. Advertising

  2. "Foodbank" <> wrote in message
    news:...
    > I have to write a program that will use linked lists to print the
    > number of unique words, total words, and the most frequent word from a
    > text file.

    ....
    > //***********help here and below
    > void add_to_list(char *word_buff) {
    > /* *CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS
    > /* ** CODE TO MAKE NEW ELEMENTS FOR BRAND NEW WORDS
    >
    >
    > void list_walk() {
    > /* ****** CODE TO WALK THE LIST AND GATHER THE STATS
    > }


    This problem has as much to do with C as with Pascal, Basic, Assembly
    language, etc etc.
    It's a homework. The simplest, I must say. Instead of asking, think over
    what is a linked list. Draw it if you don't understand things unless they're
    visualized. If you have no idea what a linked list is, read your book(s),
    lecture note(s), ask your teacher, or search the internet, but this I
    believe is something you are able to do w/o asking for any help.

    Alex
    Alexei A. Frounze, Oct 2, 2005
    #2
    1. Advertising

  3. Foodbank

    Flash Gordon Guest

    Foodbank wrote:
    > Hi,
    >
    > I have to write a program that will use linked lists to print the
    > number of unique words, total words, and the most frequent word from a
    > text file. I've gotten a decent amount of it done except for the
    > linked lists. I did not paste my code that tells the machine what a
    > word is, it works fine and it'll be easier to read that way without it.
    > Below is the code:
    >
    > //****code from here to next section is good, I don't need help
    > there****//
    > #include <stdio.h>
    > #include <string.h>
    > #include <stdlib.h>
    > struct list_elem {
    > char *word;
    > int count;
    > struct list_elem *next;
    > };
    >
    > struct list_elem *head; /* the head pointer is initially NULL */


    I would have declared the head within main using a more explicit name
    such as word_head and then passed it as a parameter.

    > //**************************
    > //***********help here and below
    > void add_to_list(char *word_buff) {
    > /* *CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS
    > /* ** CODE TO MAKE NEW ELEMENTS FOR BRAND NEW WORDS


    So try writing the code and we will help you with any specific problems
    in C coding you have. I'm sure your tutor has either explained linked
    lists of given you suitable reference material to read. We try to avoid
    actually doing peoples homework for them.

    > void list_walk() {
    > /* ****** CODE TO WALK THE LIST AND GATHER THE STATS


    You probably need some mechanism for returning the stats.

    > }
    >
    > Any help is greatly appreciated.


    Make your best effort. Getting us to do your homework won't help you to
    learn. If you can't even start then you really need to discuss it with
    your tutor since obviously the class is not working for you.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Oct 2, 2005
    #3
  4. Foodbank

    Foodbank Guest

    Hi guys, I've read more about linked lists and have a better idea of
    what they are now. I've added some code, could you please check it out
    and possibly help me with what's missing?

    Thanks,
    James

    PS This isn't homework, I'm self-teaching myself C in order to change
    job positions (more programming oriented than my current position). I
    guess in one regard it is homework, but it's for my own good, not for a
    grade. I do appreciate the input up to this point.


    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    struct list_elem {
    char *word;
    int count;
    struct list_elem *next;
    };

    struct list_elem *head;

    int get_word(char *);
    void add_to_list(char *);
    void list_walk(void);

    int unique_words, total_words;
    struct list_elem *most_frequent_elem;

    main() {
    char word_buff[100];
    while(get_word(word_buff))
    add_to_list(word_buff);
    list_walk();
    printf("there are %d unique words out of %d total words\n",
    unique_words, total_words);
    printf("the most frequent word is <%s> which used %d times\n",
    most_frequent_elem->word, most_frequent_elem->count);
    }

    void add_to_list(char *word_buff) {

    /* ***** SECTION TO SEARCH THE LINKED LIST AND COUNT ANY
    REPEATED WORDS****//
    //MY MEASLY START, NOT SURE IF CORRECT
    count=malloc(strlen(word(buff)+1));

    /* ***** MAKE NEW ELEMENTS FOR BRAND NEW WORDS *****/

    //WHAT I'VE GOTTEN SO FAR
    sizeof(struct list_elem);
    malloc(sizeof(list_elem));
    }

    void list_walk() {
    /* ****** CODE TO WALK THE LIST AND GATHER THE STATS ***** */

    struct list_elem *lp; int n=0;
    for(lp=head; lp!=NULL; lp=lp->next)
    n++;


    }

    //CODE DOESN'T NEED MODIFIED, I USED IT FROM AN OLD PROGRAM THAT TELLS
    THE COMPILER WHAT A WORD IS
    #include <ctype.h>
    /* Leave this routine EXACTLY as it stands */
    int get_word(char *s) {
    int c;
    do {
    c = getchar();
    if(c == EOF)
    return(0);
    } while(!isalpha(c) && !isdigit(c));
    do {
    if(isupper(c))
    c = tolower(c);
    *s++ = c;
    c = getchar();
    } while(isalpha(c) || isdigit(c));
    *s = 0;
    return(1);
    }



    Any help is greatly appreciated.

    Thanks,
    James
    Foodbank, Oct 2, 2005
    #4
  5. On 2 Oct 2005 15:03:43 -0700, "Foodbank" <> wrote:

    >Hi guys, I've read more about linked lists and have a better idea of
    >what they are now. I've added some code, could you please check it out
    >and possibly help me with what's missing?
    >
    >Thanks,
    >James
    >
    >PS This isn't homework, I'm self-teaching myself C in order to change
    >job positions (more programming oriented than my current position). I
    >guess in one regard it is homework, but it's for my own good, not for a
    >grade. I do appreciate the input up to this point.
    >
    >
    >#include <stdio.h>
    >#include <string.h>
    >#include <stdlib.h>
    >struct list_elem {


    Adopt a consist style of indenting. It has one of the largest returns
    on investment of any programming technique.

    >char *word;
    >int count;
    >struct list_elem *next;
    >};
    >
    >struct list_elem *head;
    >
    >int get_word(char *);
    >void add_to_list(char *);
    >void list_walk(void);
    >
    >int unique_words, total_words;
    >struct list_elem *most_frequent_elem;
    >
    >main() {
    >char word_buff[100];
    >while(get_word(word_buff))
    >add_to_list(word_buff);
    >list_walk();
    >printf("there are %d unique words out of %d total words\n",
    >unique_words, total_words);
    >printf("the most frequent word is <%s> which used %d times\n",
    >most_frequent_elem->word, most_frequent_elem->count);


    You do not handle the degenerative case where there is no input.

    >}


    It is considered good style to clean up your allocations when done
    with them. While most OSs will probably do this for you when your
    program exits, think of the case where your program later becomes part
    of a larger application.

    >
    >void add_to_list(char *word_buff) {
    >
    >/* ***** SECTION TO SEARCH THE LINKED LIST AND COUNT ANY
    >REPEATED WORDS****//
    >//MY MEASLY START, NOT SURE IF CORRECT


    How would you do this using paper and pencil. The technique is the
    same.

    If this is the first word, create a node and save address in head.

    Else search existing nodes for same word:

    If found, increment count.

    Else create a node and link it to list

    Each time you allocate a node, you also need to allocate space for the
    word the node will point to.

    >count=malloc(strlen(word(buff)+1));


    Didn't your compiler produce an error message here? There is no
    variable count defined in your code. There is a struct member named
    count but this isn't that.

    >
    >/* ***** MAKE NEW ELEMENTS FOR BRAND NEW WORDS *****/
    >
    >//WHAT I'VE GOTTEN SO FAR
    >sizeof(struct list_elem);


    This expression is a compile time constant. After the expression is
    evaluated, the result of that evaluation is ignored. What did you
    intend to happen?

    >malloc(sizeof(list_elem));


    Calling malloc and discarding the return value is one of the easiest
    ways to create a memory leak. You probably intended to use the area
    returned by malloc to hold a new node in the list. However, at this
    time, you don't even know if you need a new node. (If the word is the
    same as an existing word in the list, you would not.)

    list_elem is not a valid type. struct list_elem is.

    >}
    >
    >void list_walk() {
    >/* ****** CODE TO WALK THE LIST AND GATHER THE STATS ***** */
    >
    >struct list_elem *lp; int n=0;
    >for(lp=head; lp!=NULL; lp=lp->next)
    >n++;
    >
    >
    >}
    >
    >//CODE DOESN'T NEED MODIFIED, I USED IT FROM AN OLD PROGRAM THAT TELLS
    >THE COMPILER WHAT A WORD IS
    >#include <ctype.h>
    >/* Leave this routine EXACTLY as it stands */
    >int get_word(char *s) {
    >int c;
    >do {
    >c = getchar();
    >if(c == EOF)
    >return(0);
    >} while(!isalpha(c) && !isdigit(c));
    >do {
    >if(isupper(c))
    >c = tolower(c);
    >*s++ = c;
    >c = getchar();
    >} while(isalpha(c) || isdigit(c));
    >*s = 0;
    >return(1);
    >}
    >
    >
    >
    >Any help is greatly appreciated.
    >
    >Thanks,
    >James



    <<Remove the del for email>>
    Barry Schwarz, Oct 3, 2005
    #5
  6. Foodbank

    Foodbank Guest

    Hi guys,

    I indented the code for easier reading. Sorry about that. Thanks
    again for the help.

    BTW, Barry, my program didn't compile.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    struct list_elem {
        char *word;
        int count;
        struct list_elem *next;
        };
    
    struct list_elem *head;
    
    int get_word(char *);
    void add_to_list(char *);
    void list_walk(void);
    
    int unique_words, total_words;
    struct list_elem *most_frequent_elem;
    
    main() {
        char word_buff[100];
        while(get_word(word_buff))
        add_to_list(word_buff);
        list_walk();
        printf("there are %d unique words out of %d total words\n",
        unique_words, total_words);
        printf("the most frequent word is <%s> which used %d
        times\n",
        most_frequent_elem->word, most_frequent_elem->count);
        }
    
    void add_to_list(char *word_buff) {
    
        //SECTION TO SEARCH THE LINKED LIST AND COUNT ANY
        //REPEATED WORDS
        //HELP HERE
    
        //NOT SURE IF RIGHT
        count=malloc(strlen(word(buff)+1));
    
        //MAKE NEW ELEMENTS FOR BRAND NEW WORDS
        //HELP HERE
    
        //WHAT I'VE GOTTEN SO FAR
        sizeof(struct list_elem);
        malloc(sizeof(list_elem));
        }
    
    void list_walk() {
        //CODE TO WALK THE LIST AND GATHER THE STATS
        //HELP HERE
    
        struct list_elem *lp; int n=0;
        for(lp=head; lp!=NULL; lp=lp->next)
            n++;
        }
    
    
    //CODE BELOW DOESN'T NEED MODIFIED, I USED IT FROM AN OLD PROGRAM THAT
    TELLS THE COMPILER WHAT A WORD IS
    #include <ctype.h>
    int get_word(char *s) {
        int c;
        do {
            c = getchar();
            if(c == EOF)
            return(0);
            }
    while(!isalpha(c) && !isdigit(c));
        do {
            if(isupper(c))
            c = tolower(c);
            *s++ = c;
            c  = getchar();
            }
    while(isalpha(c) || isdigit(c));
        *s = 0; 
        return(1); 
    } 
    
    Foodbank, Oct 3, 2005
    #6
  7. Foodbank

    Foodbank Guest

    Hi all, thanks for the replies so far.

    I've made some progress. My code is below. At the end of the code are
    the errors I'm receiving.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    struct list_elem {
    	char *word;
    	int count;
    	struct list_elem *next;
            };
    struct list_elem *head;
    
    int get_word(char *);
    void add_to_list(char *);
    void list_walk(void);
    
    int unique_words, total_words;
    struct list_elem *most_frequent_elem;
    
    main() {
    	char word_buff[100];
    	while(get_word(word_buff))
    		add_to_list(word_buff);
    	list_walk();
    	printf("there are %d unique words out of %d total words\n",
    		unique_words, total_words);
    	printf("the most frequent word is <%s> which used %d times\n",
    		most_frequent_elem->word, most_frequent_elem->count);
           }
    
    void add_to_list(char *word_buff) {
    	//CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS
    
    	head->word = malloc(strlen(word_buff)+1);
    
            //CODE TO MAKE NEW ELEMENTS FOR BRAND NEW WORDS
    
           //new list element
           if(!head)
                  head = malloc(sizeof(list_elem));
               else
               {
               struct list_elem* tmp = head;
               head = malloc(sizeof(list_elem));
               head->next = head;
               }
    }
    
    void list_walk() {
    	//CODE TO WALK THE LIST AND GATHER THE STATS
    
    	struct list_elem *lp; int n=0;
    	for(lp=head; lp!=NULL; lp=lp->next)
    	n++;
    	}
    
    #include <ctype.h>
    /* Leave this routine EXACTLY as it stands */
    int get_word(char *s) {
    	int c;
    	do {
    		c = getchar();
    		if(c == EOF)
    			return(0);
    	} while(!isalpha(c) && !isdigit(c));
    	do {
    		if(isupper(c))
    			c = tolower(c);
    		*s++ = c;
    		c = getchar();
    	} while(isalpha(c) || isdigit(c));
    	*s = 0;
    	return(1);
    }
    
    
    Errors:

    In function `add_to_list':
    error: `list_elem' undeclared (first use in this function)
    error: (Each undeclared identifier is reported only once
    error: for each function it appears in.)

    error: `list_elem' undeclared (first use in this function) is referring
    to
    head = malloc(sizeof(list_elem));

    Thanks again,
    James
    Foodbank, Oct 3, 2005
    #7
  8. Foodbank wrote:
    > Hi all, thanks for the replies so far.
    >
    > I've made some progress. My code is below. At the end of the code are
    > the errors I'm receiving.

    [...]


    > In function `add_to_list':
    > error: `list_elem' undeclared (first use in this function)


    You have no type list_elem. You have the type 'struct list_elem'
    Martin Ambuhl, Oct 3, 2005
    #8
  9. Foodbank

    Default User Guest

    Foodbank wrote:

    > Hi guys,
    >
    > I indented the code for easier reading. Sorry about that. Thanks
    > again for the help.


    Please read my .sig. There's been a long discussion about this very
    point ongoing in another thread.


    Brian
    --
    Please quote enough of the previous message for context. To do so from
    Google, click "show options" and use the Reply shown in the expanded
    header.
    Default User, Oct 3, 2005
    #9
  10. On 3 Oct 2005 06:26:46 -0700, "Foodbank" <> wrote:

    >Hi all, thanks for the replies so far.
    >
    >I've made some progress. My code is below. At the end of the code are
    >the errors I'm receiving.
    >
    >
    Code:
    >#include <stdio.h>
    >#include <string.h>
    >#include <stdlib.h>
    >struct list_elem {
    >	char *word;
    >	int count;
    >	struct list_elem *next;
    >        };
    >struct list_elem *head;[/color]
    
    head is automatically initialized to NULL.
    [color=blue]
    >
    >int get_word(char *);
    >void add_to_list(char *);
    >void list_walk(void);
    >
    >int unique_words, total_words;
    >struct list_elem *most_frequent_elem;
    >
    >main() {
    >	char word_buff[100];
    >	while(get_word(word_buff))
    >		add_to_list(word_buff);
    >	list_walk();
    >	printf("there are %d unique words out of %d total words\n",
    >		unique_words, total_words);
    >	printf("the most frequent word is <%s> which used %d times\n",
    >		most_frequent_elem->word, most_frequent_elem->count);
    >       }
    >
    >void add_to_list(char *word_buff) {
    >	//CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS
    >
    >	head->word = malloc(strlen(word_buff)+1);[/color]
    
    After getting the first word, you attempt to dereference head.  This
    causes undefined behavior.  On a decent system, your program will
    abort with some useful error message.  This could be inside the
    following if but it would be better to have it follow your if else
    since whenever you create a new node you need to create a place for it
    to point to.
    [color=blue]
    >
    >        //CODE TO MAKE NEW ELEMENTS FOR BRAND NEW WORDS
    >
    >       //new list element
    >       if(!head)
    >              head = malloc(sizeof(list_elem));
    >           else
    >           {
    >           struct list_elem* tmp = head;
    >           head = malloc(sizeof(list_elem));
    >           head->next = head;[/color]
    
    Obviously you meant head->next = tmp.
    
    This will allow you to add the new node at the beginning of the linked
    list but you don't know yet if you even need it.  What happens if this
    word is a duplicate of one already in the list.
    [color=blue]
    >           }[/color]
    
    You never copied the current word to the area the new node points to.
    All of you nodes are useless without this.
    [color=blue]
    >}
    >
    >void list_walk() {
    >	//CODE TO WALK THE LIST AND GATHER THE STATS
    >
    >	struct list_elem *lp; int n=0;
    >	for(lp=head; lp!=NULL; lp=lp->next)
    >	n++;[/color]
    
    What is the point of this function.  After you count the number of
    nodes, n is destroyed.
    [color=blue]
    >	}
    >
    >#include <ctype.h>
    >/* Leave this routine EXACTLY as it stands */
    >int get_word(char *s) {
    >	int c;
    >	do {
    >		c = getchar();
    >		if(c == EOF)
    >			return(0);
    >	} while(!isalpha(c) && !isdigit(c));
    >	do {
    >		if(isupper(c))
    >			c = tolower(c);
    >		*s++ = c;
    >		c = getchar();
    >	} while(isalpha(c) || isdigit(c));
    >	*s = 0;
    >	return(1);
    >}
    >
    >
    >
    >Errors:
    >
    >In function `add_to_list':
    >error: `list_elem' undeclared (first use in this function)
    >error: (Each undeclared identifier is reported only once
    >error: for each function it appears in.)
    >
    >error: `list_elem' undeclared (first use in this function) is referring
    >to
    >head = malloc(sizeof(list_elem));


    Use sizeof *head and save yourself some aggravation.

    >
    >Thanks again,
    >James



    <<Remove the del for email>>
    Barry Schwarz, Oct 4, 2005
    #10
  11. Foodbank

    Foodbank Guest

    Here's an update. It'll compile now, but when I try to count the words,
    I get a segmentation fault. I'm really unsure where to go from here.
    Any help would benefit me greatly.

    Thanks,
    James

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    struct list_elem {
            char *word;
            int count;
            struct list_elem *next;
            };
    struct list_elem *head;
    
    
    int get_word(char *);
    void add_to_list(char *);
    void list_walk(void);
    
    
    int unique_words, total_words;
    struct list_elem *most_frequent_elem;
    
    
    main() {
            char word_buff[100];
            while(get_word(word_buff))
                    add_to_list(word_buff);
            list_walk();
            printf("there are %d unique words out of %d total words\n",
                    unique_words, total_words);
            printf("the most frequent word is <%s> which used %d times\n",
                    most_frequent_elem->word, most_frequent_elem->count);
           }
    
    
    void add_to_list(char *word_buff) {
            //CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS
    
    
            head->word = malloc(strlen(word_buff)+1);
            //What should I do to increment the count, for loop?  Should I
    be using strcmp anywhere to see if it's a new word or not?
    
            //CODE TO MAKE NEW ELEMENTS FOR BRAND NEW WORDS
    
    
           //new list element
           if(!head)
                  head = malloc(sizeof(list_elem));
               else
               {
               struct list_elem* tmp = head;
               head = malloc(sizeof(list_elem));
               head->next = head;
       ////Are you sure it should be head->next = tmp; above?  What will
    this do?
               }
    }
    
    
    void list_walk() {
            //CODE TO WALK THE LIST AND GATHER THE STATS
            //Really lost on what do do here
    
    
            struct list_elem *lp; int n=0;
            for(lp=head; lp!=NULL; lp=lp->next)
            n++;
            }
    
    
    #include <ctype.h>
    /* Leave this routine EXACTLY as it stands */
    int get_word(char *s) {
            int c;
            do {
                    c = getchar();
                    if(c == EOF)
                            return(0);
            } while(!isalpha(c) && !isdigit(c));
            do {
                    if(isupper(c))
                            c = tolower(c);
                    *s++ = c;
                    c = getchar();
            } while(isalpha(c) || isdigit(c));
            *s = 0; 
            return(1); 
    
    
    
    } 
    
    
    Foodbank, Oct 4, 2005
    #11
  12. Foodbank

    Netocrat Guest

    Foodbank wrote:
    > Here's an update. It'll compile now, but when I try to count the words,
    > I get a segmentation fault. I'm really unsure where to go from here.


    Start with Barry Schwartz's suggestions, many of which you've neglected.

    [...]
    > #include <stdio.h>
    > #include <string.h>
    > #include <stdlib.h>
    > struct list_elem {
    > char *word;
    > int count;
    > struct list_elem *next;
    > };
    > struct list_elem *head;
    >
    > int get_word(char *);
    > void add_to_list(char *);
    > void list_walk(void);
    >
    > int unique_words, total_words;
    > struct list_elem *most_frequent_elem;
    >
    > main() {
    > char word_buff[100];
    > while(get_word(word_buff))
    > add_to_list(word_buff);
    > list_walk();
    > printf("there are %d unique words out of %d total words\n",
    > unique_words, total_words);
    > printf("the most frequent word is <%s> which used %d times\n",
    > most_frequent_elem->word, most_frequent_elem->count);
    > }
    >
    > void add_to_list(char *word_buff) {
    > //CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS
    >
    > head->word = malloc(strlen(word_buff)+1);


    Revisit Barry's advice re the above line. On the first call of this
    function, head is NULL and head->word is invalid. This is likely the
    cause of your segfault. It should be moved to after the malloc() for
    head below.

    > //What should I do to increment the count, for loop?


    No. Just increment the count if you find a duplicate.

    > Should I
    > be using strcmp anywhere to see if it's a new word or not?


    Yes. You need to walk the list to look for a duplicate word before
    adding it. I would suggest this be a separate function e.g.
    struct list_elem *find_in_list(char *);
    called from main before add_to_list. It would walk the list, calling
    strcmp on each entry and returning the entry if it finds a duplicate;
    returning NULL if it doesn't. Then main would increment the count of
    the returned entry or call add_to_list function if NULL was returned.

    > //CODE TO MAKE NEW ELEMENTS FOR BRAND NEW WORDS
    >
    > //new list element
    > if(!head)
    > head = malloc(sizeof(list_elem));
    > else
    > {
    > struct list_elem* tmp = head;
    > head = malloc(sizeof(list_elem));
    > head->next = head;
    > ////Are you sure it should be head->next = tmp; above?


    It will prepend the word to the list. To instead append it, you'd need
    something different.

    > What will this do?


    Turn head into a circular single-element list and leak memory by losing
    references to existing elements.

    > }


    You are not copying the word into head->word as you need to here and as
    Barry advised you to. See strcpy().

    > }
    >
    > void list_walk() {
    > //CODE TO WALK THE LIST AND GATHER THE STATS
    > //Really lost on what do do here


    You're using global variables but better practice is to either return a
    structure or pass in pointers to the return variables which can then be
    updated within the function (they would then be defined in main, rather
    than as globals). e.g.
    void list_walk(int *uniq, int *tot) {

    Then call from main as:
    list_walk(&unique_words, &total_words);

    > struct list_elem *lp; int n=0;


    Initialise *uniq and *tot to zero; remove n.

    > for(lp=head; lp!=NULL; lp=lp->next)
    > n++;


    Increment (*uniq) as you're doing for n; add lp->count to *tot.

    > }


    [...]
    --
    http://members.dodo.com.au/~netocrat
    Netocrat, Oct 4, 2005
    #12
  13. Foodbank

    Foodbank Guest

    Hi everyone,

    Thanks for all the help so far. I've made alot of progress, but I'm
    getting incorrect word counts. Can anyone check this over and see
    what's wrong?

    Ignore the printf's, as they were wrapped to the next line by the
    editor for posting this message. They're correct in my code that I'm
    using.

    Thanks,
    James

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    struct list_elem {
            char *word;
            int count;
            struct list_elem *next;
            };
    
    struct list_elem *head;
    
    int get_word(char *);
    void add_to_list(char *);
    void list_walk(void);
    
    int unique_words, total_words;
    struct list_elem *most_frequent_elem;
    
    
    main()  {
            char word_buff[100];
            while(get_word(word_buff))
                    add_to_list(word_buff);
            list_walk();
            printf("there are %d unique words out of %d total words\n",
    unique_words,total_words);
            printf("the most frequent word is <%s> which used %d
    times\n",most_frequent_elem->word, most_frequent_elem->count);
            }
    
    
    void add_to_list(char *word_buff) {
    
    
                          //CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS
    
            struct list_elem *tmp = head;
            for(tmp=head; tmp!=NULL; tmp=tmp->next)
            {
                  if(!strcmp(word_buff, tmp->word))
                     tmp->count++;
                     return;
            }
    
    
    
                          //CODE TO MAKE NEW ELEMENTS FOR BRAND NEW WORDS
    
            tmp=head;
            head = malloc(sizeof(struct list_elem));
            head->next = tmp;
    
            head->word = malloc(strlen(word_buff)+1);
            strcpy(head->word,word_buff);
    
    }
    
    void list_walk() {
    
                          //CODE TO WALK THE LIST AND GATHER THE STATS
    
            most_frequent_elem=head;
            struct list_elem *lp;
            for(lp=head; lp!=NULL; lp=lp->next)
            {
                 unique_words++;
                 total_words += lp->count;
    
                 if(lp->count > most_frequent_elem->count)
                 most_frequent_elem=lp;
            }
    }
    
    #include <ctype.h>
    /* Leave this routine EXACTLY as it stands */
    int get_word(char *s) {
            int c;
            do {
                    c = getchar();
                    if(c == EOF)
                            return(0);
            } while(!isalpha(c) && !isdigit(c));
            do {
                    if(isupper(c))
                            c = tolower(c);
                    *s++ = c;
                    c = getchar();
            } while(isalpha(c) || isdigit(c));
            *s = 0; 
            return(1); 
    
    
    
    } 
    
    Foodbank, Oct 6, 2005
    #13
  14. Foodbank

    Netocrat Guest

    On Thu, 06 Oct 2005 10:38:46 -0700, Foodbank wrote:
    [...]
    > void add_to_list(char *word_buff) {
    >
    >
    > //CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS
    >
    > struct list_elem *tmp = head;
    > for(tmp=head; tmp!=NULL; tmp=tmp->next)
    > {
    > if(!strcmp(word_buff, tmp->word))

    {
    > tmp->count++;
    > return;

    }
    > }

    [...]
    --
    http://members.dodo.com.au/~netocrat
    Netocrat, Oct 6, 2005
    #14
  15. Foodbank

    Flash Gordon Guest

    Foodbank wrote:
    > Hi everyone,
    >
    > Thanks for all the help so far. I've made alot of progress, but I'm
    > getting incorrect word counts. Can anyone check this over and see
    > what's wrong?


    How many occurrences of a word do you have when you first find it?

    > Ignore the printf's, as they were wrapped to the next line by the
    > editor for posting this message. They're correct in my code that I'm
    > using.
    >
    > Thanks,
    > James
    >
    >
    Code:
    > #include <stdio.h>
    > #include <string.h>
    > #include <stdlib.h>
    > struct list_elem {
    >         char *word;
    >         int count;
    >         struct list_elem *next;
    >         };
    > 
    > struct list_elem *head;
    > 
    > int get_word(char *);
    > void add_to_list(char *);
    > void list_walk(void);
    > 
    > int unique_words, total_words;
    > struct list_elem *most_frequent_elem;[/color]
    
    Having these as globals is bad design. They should be local to main and 
    passed as parameters.
    [color=blue]
    > main()  {[/color]
    
    main returns an int and you are not using any parameters. It is 
    advisable to make both these things explicit. The return value is 
    important because in the new C standard implicit int is no longer allowed.
    
    int main(void)
    [color=blue]
    >         char word_buff[100];[/color]
    
    How do you know there will never be a "word" longer than 99 characters?
    [color=blue]
    >         while(get_word(word_buff))
    >                 add_to_list(word_buff);
    >         list_walk();
    >         printf("there are %d unique words out of %d total words\n",
    > unique_words,total_words);
    >         printf("the most frequent word is <%s> which used %d
    > times\n",most_frequent_elem->word, most_frequent_elem->count);[/color]
    
    Since main returns an int, return a value!
               return 0;
    [color=blue]
    >         }
    > 
    > 
    > void add_to_list(char *word_buff) {
    > 
    > 
    >                       //CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS[/color]
    
    Please don't use // style comments on Usenet. They don't survive line 
    wrapping. They are also are only available as standard in the new 
    standard, and you can't be working to the new standard because you 
    defined main using an implicit int!
    [color=blue]
    >         struct list_elem *tmp = head;
    >         for(tmp=head; tmp!=NULL; tmp=tmp->next)
    >         {
    >               if(!strcmp(word_buff, tmp->word))
    >                  tmp->count++;
    >                  return;
    >         }
    > 
    > 
    > 
    >                       //CODE TO MAKE NEW ELEMENTS FOR BRAND NEW WORDS
    > 
    >         tmp=head;
    >         head = malloc(sizeof(struct list_elem));
    >         head->next = tmp;
    > 
    >         head->word = malloc(strlen(word_buff)+1);
    >         strcpy(head->word,word_buff);[/color]
    
    So what value will head->count be? What value should it be?
    [color=blue]
    > }
    > 
    > void list_walk() {
    > 
    >                       //CODE TO WALK THE LIST AND GATHER THE STATS
    > 
    >         most_frequent_elem=head;
    >         struct list_elem *lp;
    >         for(lp=head; lp!=NULL; lp=lp->next)
    >         {
    >              unique_words++;
    >              total_words += lp->count;
    > 
    >              if(lp->count > most_frequent_elem->count)
    >              most_frequent_elem=lp;
    >         }
    > }
    > 
    > #include <ctype.h>[/color]
    
    It's more common to put all your #includes at the top of the file, 
    although it is not required.
    [color=blue]
    > /* Leave this routine EXACTLY as it stands */
    > int get_word(char *s) {
    >         int c;
    >         do {
    >                 c = getchar();
    >                 if(c == EOF)
    >                         return(0);[/color]
    
    return is not a function, it does not need the parenthesis.
                               return 0;
    [color=blue]
    >         } while(!isalpha(c) && !isdigit(c));
    >         do {
    >                 if(isupper(c))
    >                         c = tolower(c);
    >                 *s++ = c;
    >                 c = getchar();
    >         } while(isalpha(c) || isdigit(c));
    >         *s = 0; [/color]
    
    If someone types in more than 99 alphanumerics in a row this will 
    overrun your buffer.
    [color=blue]
    >         return(1); [/color]
    Again
               return 1;[color=blue]
    > } 
    > 

    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Oct 6, 2005
    #15
  16. Foodbank wrote:

    > main() {

    ^^
    Please stop relying on implicit int. Especially since you use

    > void add_to_list(char *word_buff) {
    > //CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS

    ^^^
    a style of comments unsupported under the standards of C which also
    allow implicit int.

    See if your problem goes away when you fix the bracketing on

    > struct list_elem *tmp = head;
    > for(tmp=head; tmp!=NULL; tmp=tmp->next)
    > {
    > if(!strcmp(word_buff, tmp->word))
    > tmp->count++;
    > return;
    > }


    struct list_elem *tmp = head;
    for(tmp=head; tmp!=NULL; tmp=tmp->next)
    if(!strcmp(word_buff, tmp->word))
    {
    tmp->count++;
    return;
    }
    Martin Ambuhl, Oct 6, 2005
    #16
  17. Foodbank

    Foodbank Guest

    I got it working guys. I really appreciate the help.

    Take care,
    James
    Foodbank, Oct 7, 2005
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Ritchey
    Replies:
    7
    Views:
    479
    emerth
    Jul 10, 2003
  2. Chris Ritchey

    Generating a char* from a linked list of linked lists

    Chris Ritchey, Jul 9, 2003, in forum: C Programming
    Replies:
    7
    Views:
    466
    emerth
    Jul 10, 2003
  3. =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==

    List of lists of lists of lists...

    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==, May 8, 2006, in forum: Python
    Replies:
    5
    Views:
    404
    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==
    May 15, 2006
  4. fool
    Replies:
    14
    Views:
    505
    Barry Schwarz
    Jul 3, 2006
  5. jawdoc
    Replies:
    9
    Views:
    752
    Chris Thomasson
    Mar 10, 2008
Loading...

Share This Page