Linked Lists

F

Foodbank

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
 
A

Alexei A. Frounze

Foodbank said:
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
 
F

Flash Gordon

Foodbank said:
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.
 
F

Foodbank

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
 
B

Barry Schwarz

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>>
 
F

Foodbank

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); 
}
 
F

Foodbank

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
 
M

Martin Ambuhl

Foodbank said:
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'
 
D

Default User

Foodbank said:
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
 
B

Barry Schwarz

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;[/QUOTE]

head is automatically initialized to NULL.
[QUOTE]
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);[/QUOTE]

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.
[QUOTE]
//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;[/QUOTE]

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.
[QUOTE]
}[/QUOTE]

You never copied the current word to the area the new node points to.
All of you nodes are useless without this.
[QUOTE]
}

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++;[/QUOTE]

What is the point of this function.  After you count the number of
nodes, n is destroyed.
[QUOTE]
}

#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>>
 
F

Foodbank

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); 



}
 
N

Netocrat

Foodbank said:
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.

[...]
 
F

Foodbank

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); 



}
 
N

Netocrat

]
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; }
}
[...]
 
F

Flash Gordon

Foodbank said:
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;[/QUOTE]

Having these as globals is bad design. They should be local to main and 
passed as parameters.
[QUOTE]
main()  {[/QUOTE]

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)
[QUOTE]
char word_buff[100];[/QUOTE]

How do you know there will never be a "word" longer than 99 characters?
[QUOTE]
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);[/QUOTE]

Since main returns an int, return a value!
           return 0;
[QUOTE]
}


void add_to_list(char *word_buff) {


//CODE TO SEARCH THE LIST AND COUNT REPEAT WORDS[/QUOTE]

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!
[QUOTE]
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);[/QUOTE]

So what value will head->count be? What value should it be?
[QUOTE]
}

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>[/QUOTE]

It's more common to put all your #includes at the top of the file, 
although it is not required.
[QUOTE]
/* Leave this routine EXACTLY as it stands */
int get_word(char *s) {
int c;
do {
c = getchar();
if(c == EOF)
return(0);[/QUOTE]

return is not a function, it does not need the parenthesis.
                           return 0;
[QUOTE]
} while(!isalpha(c) && !isdigit(c));
do {
if(isupper(c))
c = tolower(c);
*s++ = c;
c = getchar();
} while(isalpha(c) || isdigit(c));
*s = 0; [/QUOTE]

If someone types in more than 99 alphanumerics in a row this will 
overrun your buffer.
[QUOTE]
return(1); [/QUOTE]
Again
           return 1;[QUOTE]
}
 
M

Martin Ambuhl

Foodbank said:
^^
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;
}
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top