Re: A little bit of help regarding my linked list program required. - "words.c" - "words.c"

Discussion in 'C Programming' started by Richard Heathfield, Oct 4, 2003.

  1. BareFoot_XR6 <> wrote:

    > attached the wrong version of code :(


    When I saw that you'd attached code instead of including it directly in your
    article, I moved straight to the next article. Then I had a change of
    heart, and decided to at least mention that I'm not the only one who
    ignores attachments. If you want help, I suggest that you put your code in
    the article itself, rather than in an attachment.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Oct 4, 2003
    #1
    1. Advertising

  2. Richard Heathfield

    BareFoot_XR6 Guest

    Re: A little bit of help regarding my linked list program required. (No attachment this time)

    Too easy, the code is as follows. It is very messy and I am still in the
    creation stage. Basically what is happening is when a word occurs in the file
    it also records the line it occured on, however it is not asigning the first
    line that it occurs on and instead is printing rubbish followed by all the
    lines after the first occurence of the word. Sorry in advance for posting so
    much code. just ensure you have your input redirected to a file to run

    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    #include <stdlib.h>
    struct node
    { struct node *next; /*
    pointer to next link in list */
    char *word;
    /* word for this tree */
    int count;
    int line;
    int lines[200];
    };

    /* the first pointer to the list*/

    static struct node *root = NULL;

    void memory_error(void)
    {
    printf("Error:Out of memory\n");
    exit(8);
    }

    char *save_string(char *string)
    {
    char *new_string;
    new_string = malloc((strlen(string) + 1)); //points to the new
    allocated memory
    if (new_string == NULL)
    memory_error();
    //couldn't allocate memory so program quits
    strcpy(new_string, string);
    //copy the string into the new memory location
    return (new_string);
    }

    void enter(struct node **node, char **word, int line)
    {
    int result; /*
    result of strcmp */
    int i;
    char *save_string(char *); /* save a
    string on the heap */

    /* If the current node is null, we
    have reached the
    end of the list
    and must create a new node. */
    if ((*node) == NULL)
    {
    /* Allocate memory for a new node */
    (*node) = malloc(sizeof(struct node));
    for (i=0;i<200;i++)
    (*node)->lines = 500;
    if ((*node) == NULL)


    memory_error(); /* Initialize the new node */
    for (i=0;i<100;i++) /*This is the part I am

    having trouble
    with*/
    {
    if ((*node)->lines == 500) //if it is 500 then it can be allocated a
    line
    //number
    {
    //but it
    doesn't seem to want to allocate it ??
    (*node)->lines = line;
    break;
    }
    }

    (*node)->count = 1;
    (*node)->next = NULL;
    (*node)->word = save_string(*word);
    return;
    }

    result = strcmp((*node)->word, *word); /* The current node already
    contains the word, no entry necessary */
    if (result == 0) {
    for (i=0;i<100;i++)
    {
    if((*node)->lines == 500) //since it is initialised to
    500 if it still
    {
    //equals 500 then
    it can be added to
    (*node)->lines = line;
    break;
    }
    }

    (*node)->count++; //increase the number of
    occurences

    return;

    }

    enter(&(*node)->next, &*word, line);
    }

    void scan()
    { static char buffer[8192] = {0}; //input buffer
    char *word = NULL;
    int line = 0;
    char *c;
    char *seps = " \t\n\r\a\f\v!\"%^&*()_=+{}[]\\|/,.<>:;#~?-";
    //word seperators when reading file


    while((fgets(buffer, sizeof buffer, stdin)) != NULL)
    {
    line++;
    printf("%d\n", line);
    if ((word = strtok(buffer, seps)) != NULL)
    {

    for (c=word;*c!='\0';++c)
    {
    *c = tolower(*c); //convert all input to lowercase for easy comparison
    }


    enter(&root, &word, line);
    }

    while((word = strtok(NULL, seps)) != NULL)
    {
    for (c=word;*c!='\0';++c)
    {
    *c = tolower(*c);
    }

    enter(&root, &word, line);
    }

    }
    }

    void print_tree(struct node *nodeprint)
    {
    int i;


    if (nodeprint == NULL)
    return; //end of list

    printf("%18s%5s(%5d)%5s%5d", nodeprint->word, "",nodeprint->count,"");
    for (i=0;i<100;i++)
    {
    if (nodeprint->lines == 500)
    //nodeprint->lines is initialised to all
    break; //500 so if it is still 500 it

    //has not
    //been changed

    //and hence it does not
    get printed
    printf("%d ",nodeprint->lines);
    }
    printf("\n");
    print_tree(nodeprint->next);
    }

    int main()
    {

    scan();


    printf("%18s%5s(%5s)\n\n","WORD","","COUNT");
    print_tree(root);
    return (0);
    }
     
    BareFoot_XR6, Oct 4, 2003
    #2
    1. Advertising

  3. Richard Heathfield

    CBFalconer Guest

    Re: A little bit of help regarding my linked list program required. -"words.c" - "words.c"

    Richard Heathfield wrote:
    > BareFoot_XR6 <> wrote:
    >
    > > attached the wrong version of code :(

    >
    > When I saw that you'd attached code instead of including it
    > directly in your article, I moved straight to the next article.
    > Then I had a change of heart, and decided to at least mention
    > that I'm not the only one who ignores attachments. If you want
    > help, I suggest that you put your code in the article itself,
    > rather than in an attachment.


    Me too, except that in moving on I found Richards reply. So I'll
    add to it:

    When you paste your source into your article, make sure that
    source has no tab characters (use spaces), that lines are no more
    than 72 chars long, and that you do not use // comments (which
    fare badly under line wraps). It can be useful to demarcate the
    start and end of your file with lines like:

    /*------- begin/end file xxx.x ----------*/

    Attachments are a security risk, and usenet is a text only medium.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Oct 4, 2003
    #3
  4. Richard Heathfield

    CBFalconer Guest

    Re: A little bit of help regarding my linked list program required. (Noattachment this time)

    BareFoot_XR6 wrote:
    >
    > Too easy, the code is as follows. It is very messy and I am still in the

    ..... snip ....

    > //nodeprint->lines is initialised to all
    > break; //500 so if it is still 500 it
    >
    > //has not
    > //been changed
    >
    > //and hence it does not
    > get printed

    ..... snip ....

    Oh dear. You didn't read my addendum to Richards comments.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Oct 4, 2003
    #4
  5. Richard Heathfield

    BareFoot_XR6 Guest

    Re: A little bit of help regarding my linked list program required. READ THIS ONE FIRST

    >When you paste your source into your article, make sure that
    >source has no tab characters (use spaces), that lines are no more
    >than 72 chars long, and that you do not use // comments (which
    >fare badly under line wraps). It can be useful to demarcate the
    >start and end of your file with lines like:


    I was in the posting process as you posted this so let me try again :(

    -----------------------------CODE
    START------------------------------------------
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    #include <stdlib.h>

    struct node
    {
    struct node *next;
    char *word;
    int count;
    int line;
    int lines[200];
    };

    static struct node *root = NULL;

    void memory_error(void)
    {
    printf("Error: Insufficient memory\n");
    exit(8);
    }


    char *save_string(char *string)
    {

    char *new_string;

    new_string = malloc((strlen(string) + 1));

    if (new_string == NULL)

    memory_error();

    strcpy(new_string, string);

    return (new_string);

    }

    void enter(struct node **node, char **word, int line)
    {
    int result;
    int i;
    char *save_string(char *);

    if ((*node) == NULL) {

    (*node) = malloc(sizeof(struct node));

    for (i=0;i<200;i++)

    (*node)->lines = 500;

    if ((*node) == NULL)

    memory_error();

    for (i=0;i<100;i++)
    {
    if ((*node)->lines == 500)
    {
    (*node)->lines = line;
    break;
    }
    }

    /*The part just above in the for loop seems to be my problem.*/

    (*node)->count = 1;
    (*node)->next = NULL;
    (*node)->word = save_string(*word);
    return;
    }

    result = strcmp((*node)->word, *word);
    if (result == 0) {
    for (i=0;i<100;i++)
    {
    if((*node)->lines == 500)
    {
    (*node)->lines = line;
    break;
    }
    }

    (*node)->count++;

    return;

    }

    enter(&(*node)->next, &*word, line);
    }


    void scan()
    { static char buffer[8192] = {0};
    char *word = NULL;
    int line = 0;
    char *c;
    char *seps = " \t\n\r\a\f\v!\"%^&*()_=+{}[]\\|/,.<>:;#~?-";


    while((fgets(buffer, sizeof buffer, stdin)) != NULL)
    {
    line++;
    printf("%d\n", line);
    if ((word = strtok(buffer, seps)) != NULL)
    {

    for (c=word;*c!='\0';++c)
    {
    *c = tolower(*c);
    }


    enter(&root, &word, line);
    }

    while((word = strtok(NULL, seps)) != NULL)
    {
    for (c=word;*c!='\0';++c)
    {
    *c = tolower(*c);
    }

    enter(&root, &word, line);
    }

    }
    }


    void print_tree(struct node *nodeprint)
    {
    int i;


    if (nodeprint == NULL)
    return;

    printf("%18s%5s(%5d)%5s%5d", nodeprint->word, "",nodeprint->count,"");
    for (i=0;i<100;i++)
    {
    if (nodeprint->lines == 500)
    break;

    printf("%d ",nodeprint->lines);
    }
    printf("\n");
    print_tree(nodeprint->next);
    }


    int main()
    {

    scan();

    printf("%18s%5s(%5s)\n\n","WORD","","COUNT");
    print_tree(root);
    return (0);
    }


    ----------------------------------------------------END
    CODE----------------------------------------------

    The output with input redirection to a test file containing the following text:

    Hello My Name is Brett
    What is your name?

    Wow, wow that is tops!

    hello, brett

    name

    is:

    WORD (COUNT)

    hello ( 2) 12450561 6
    my ( 1) 12449681
    name ( 3) 12448761 2 8
    is ( 3) 12447841 2 4
    brett ( 2) 12446921 6
    what ( 1) 12446002
    your ( 1) 12445082
    wow ( 2) 12444164 4
    that ( 1) 12443244
    tops ( 1) 12442324

    The numbers after the counts are the line numbers in which the words occur on,
    they all print correctly except for the first one.

    Sorry for such a long post but this has me stumped.
    Thanks,
    Brett
     
    BareFoot_XR6, Oct 5, 2003
    #5
  6. Richard Heathfield

    barefoot_XR6 Guest

    I found the problem, thanks for the tips for my future postings. See inside if interested in problem.


    >void print_tree(struct node *nodeprint)
    >{
    > int i;
    >
    >
    > if (nodeprint == NULL)
    > return;
    >
    > printf("%18s%5s(%5d)%5s%5d", nodeprint->word, "",nodeprint->count,"");
    > <========= Problem is here

    it is trying to print
    a variable that is not there.
    > for (i=0;i<100;i++)
    > {
    > if (nodeprint->lines == 500)
    > break;
    >
    > printf("%d ",nodeprint->lines);
    > }
    > printf("\n");
    > print_tree(nodeprint->next);
    > }
     
    barefoot_XR6, Oct 5, 2003
    #6
  7. Richard Heathfield

    CBFalconer Guest

    Re: A little bit of help regarding my linked list program required. READTHIS ONE FIRST

    BareFoot_XR6 wrote:
    >
    > >When you paste your source into your article, make sure that
    > >source has no tab characters (use spaces), that lines are no more
    > >than 72 chars long, and that you do not use // comments (which
    > >fare badly under line wraps). It can be useful to demarcate the
    > >start and end of your file with lines like:

    >
    > I was in the posting process as you posted this so let me try again :(
    >
    > -----------------------------CODE
    > START------------------------------------------
    > #include <stdio.h>
    > #include <ctype.h>
    > #include <string.h>
    > #include <stdlib.h>
    >
    > struct node
    > {
    > struct node *next;
    > char *word;
    > int count;
    > int line;
    > int lines[200];
    > };


    You are obviously still using tabs and lines of more than 72 char
    length. This doesn't work when posting code. Maybe you are using
    some sort of variable width font in your newsreader editor, if so,
    don't.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Oct 5, 2003
    #7
  8. Re: A little bit of help regarding my linked list program required. READ THIS ONE FIRST

    On 5 Oct 2003 09:54:16 +1000, BareFoot_XR6 <> wrote:

    snip
    >-----------------------------CODE
    >START------------------------------------------
    >#include <stdio.h>
    >#include <ctype.h>
    >#include <string.h>
    >#include <stdlib.h>
    >
    >struct node
    > {
    > struct node *next;
    > char *word;
    > int count;
    > int line;
    > int lines[200];
    >};
    >
    >static struct node *root = NULL;
    >
    >void memory_error(void)
    >{
    > printf("Error: Insufficient memory\n");
    > exit(8);
    >}
    >
    >
    >char *save_string(char *string)
    >{
    >
    > char *new_string;
    >
    > new_string = malloc((strlen(string) + 1));
    >
    > if (new_string == NULL)
    >
    > memory_error();
    >
    > strcpy(new_string, string);
    >
    > return (new_string);
    >
    >}
    >
    >void enter(struct node **node, char **word, int line)
    >{
    > int result;
    > int i;
    > char *save_string(char *);


    Please learn to indent consistently. Unreadable code is that much
    harder to debug.

    >
    > if ((*node) == NULL) {
    >
    > (*node) = malloc(sizeof(struct node));


    Please.

    >
    > for (i=0;i<200;i++)
    >
    > (*node)->lines = 500;


    Since you never have a line 0 but could have a line 500, 0 would be a
    better choice for an unused element.

    >
    > if ((*node) == NULL)
    >
    > memory_error();


    This if needs to be before the preceding for . You must check the
    result of malloc before you attempt to use it.

    >
    > for (i=0;i<100;i++)


    Why 100 when the array contains 200 elements?

    By the way, this loop is irrelevant. Since you just initialized all
    of lines to 500, this code will always set lines[0] to line.

    > {
    > if ((*node)->lines == 500)
    > {
    > (*node)->lines = line;
    > break;
    > }
    > }
    >
    >/*The part just above in the for loop seems to be my problem.*/


    No, your problem is later on.

    >
    > (*node)->count = 1;
    > (*node)->next = NULL;
    > (*node)->word = save_string(*word);
    > return;
    > }
    >
    > result = strcmp((*node)->word, *word);
    > if (result == 0) {
    > for (i=0;i<100;i++)


    100? Here it is significant.

    > {
    > if((*node)->lines == 500)
    > {
    > (*node)->lines = line;
    > break;
    > }
    > }
    >
    > (*node)->count++;
    >
    > return;
    >
    > }
    >
    > enter(&(*node)->next, &*word, line);
    >}
    >
    >
    >void scan()
    >{ static char buffer[8192] = {0};
    > char *word = NULL;
    > int line = 0;
    > char *c;
    > char *seps = " \t\n\r\a\f\v!\"%^&*()_=+{}[]\\|/,.<>:;#~?-";
    >
    >
    > while((fgets(buffer, sizeof buffer, stdin)) != NULL)
    > {
    > line++;
    > printf("%d\n", line);
    > if ((word = strtok(buffer, seps)) != NULL)
    > {
    >
    > for (c=word;*c!='\0';++c)
    > {
    > *c = tolower(*c);
    > }
    >
    >
    > enter(&root, &word, line);
    > }
    >
    > while((word = strtok(NULL, seps)) != NULL)
    > {
    > for (c=word;*c!='\0';++c)
    > {
    > *c = tolower(*c);
    > }
    >
    > enter(&root, &word, line);
    > }
    >
    > }
    >}
    >
    >
    >void print_tree(struct node *nodeprint)
    >{
    > int i;
    >
    >
    > if (nodeprint == NULL)
    > return;
    >
    > printf("%18s%5s(%5d)%5s%5d", nodeprint->word, "",nodeprint->count,"");


    Here is your problem. You have five format specifiers in your format
    string. Unfortunately, you have only four parameters following. Who
    knows what the last %5d will "do"? Once I eliminated it, the code ran
    fine on my simple test case with two lines.

    > for (i=0;i<100;i++)


    100 again?

    > {
    > if (nodeprint->lines == 500)
    > break;
    >
    > printf("%d ",nodeprint->lines);
    > }
    > printf("\n");
    > print_tree(nodeprint->next);
    > }
    >
    >
    >int main()
    >{
    >
    > scan();
    >
    > printf("%18s%5s(%5s)\n\n","WORD","","COUNT");
    > print_tree(root);
    > return (0);
    >}
    >
    >
    >----------------------------------------------------END
    >CODE----------------------------------------------
    >
    >The output with input redirection to a test file containing the following text:
    >
    >Hello My Name is Brett
    >What is your name?
    >
    >Wow, wow that is tops!
    >
    >hello, brett
    >
    >name
    >
    >is:
    >
    > WORD (COUNT)
    >
    > hello ( 2) 12450561 6
    > my ( 1) 12449681
    > name ( 3) 12448761 2 8
    > is ( 3) 12447841 2 4
    > brett ( 2) 12446921 6
    > what ( 1) 12446002
    > your ( 1) 12445082
    > wow ( 2) 12444164 4
    > that ( 1) 12443244
    > tops ( 1) 12442324
    >
    >The numbers after the counts are the line numbers in which the words occur on,
    >they all print correctly except for the first one.
    >




    <<Remove the del for email>>
     
    Barry Schwarz, Oct 5, 2003
    #8
    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:
    484
    emerth
    Jul 10, 2003
  2. fool
    Replies:
    14
    Views:
    514
    Barry Schwarz
    Jul 3, 2006
  3. joshd
    Replies:
    12
    Views:
    675
    John Carson
    Oct 2, 2006
  4. jawdoc
    Replies:
    9
    Views:
    762
    Chris Thomasson
    Mar 10, 2008
  5. Replies:
    2
    Views:
    243
    Harold Aptroot
    Feb 13, 2009
Loading...

Share This Page