Thread: Counting the times 'beer' is used in a txt file.

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    3

    Counting the times 'beer' is used in a txt file.

    Hello,

    I'm running into problems with a little program I'm writing for a homework assignment. I need to count the number of times 'beer' is used in this song:

    99 bottles of beer on the wall, 99 bottles of beer.
    Take one down and pass it around, 98 bottles of beer on the wall.
    98 bottles of beer on the wall, 98 bottles of beer.
    Take one down and pass it around, 97 bottles of beer on the wall.
    97 bottles of beer on the wall, 97 bottles of beer.
    Take one down and pass it around, 96 bottles of beer on the wall.
    96 bottles of beer on the wall, 96 bottles of beer.
    Take one down and pass it around, 95 bottles of beer on the wall.
    It looks quite simple and looks correct in my eyes, count however always stays 0.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAX 500
    
    char line[MAX];
    FILE * pf;
    int count = 0;
    int main()
    {
        pf = fopen("beer.txt" , "r");           /* open file for reading */
        while (fgets(line, MAX, pf) != NULL)    /* while there's another line */
        {
            if (strcmp(line, "beer") == 0)      /* if the pattern matches */
            {
                ++count;                        /* add 1 to count */
            }
        }
        printf ("%d", count);                   /* print the result */
        fclose(pf);
        return 0;
    }
    Any suggestions?

    Thank you.

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Your strcmp() is checking if your entire line is beer, not if beer is contained in your line.

    Jim

  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    strcmp() compares whole strings... you need to find a string buried in a larger string...
    Look up strstr() in your compiler's library documentation.
    Also note that you'll need a loop to find multiple occurances on a single line.

    FWIW... a much better way of doing this kind of search is to load the entire file as a single string then search the string, counting as you go.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > FWIW... a much better way of doing this kind of search is to load the entire file as a single string
    No normal person tries to load a file of unknown length into memory only to use each byte of it only once.

    Long before you've actually run out of memory, the start of the file (in memory) is busy being swapped out so you can read the end of the file into memory.

    Then you start processing the file, so back in comes the start of the file from swap, and out goes the end of the file.

    Scanning the file one line at a time is perfectly reasonable, and works just the same regardless of the input file size.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Nov 2011
    Posts
    3
    Quote Originally Posted by CommonTater View Post
    strcmp() compares whole strings... you need to find a string buried in a larger string...
    Look up strstr() in your compiler's library documentation.
    Also note that you'll need a loop to find multiple occurances on a single line.

    FWIW... a much better way of doing this kind of search is to load the entire file as a single string then search the string, counting as you go.
    Thank you though I can't seem to figure out how to make it loop, I can only get it to count the first occurence if there is one on the line.

    This is what I have now:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAX 500
    int count = 0;
    char string[MAX];
    FILE * pf;
    int main()
    {
        pf = fopen("beer.txt", "r");            /* open file for reading */
        while(fgets(string, MAX, pf) != NULL)   /* while there's another line */
        {
            printf("%s", string);
            if (strstr (string, "beer"))        /* if beer is found in the string */
            count++;                            /* add 1 to count */
        }
        printf("\n%d\n", count);
        return 0;
    }
    I've tried using fgetc, but that doesn't seem to work, I guess I need it to continue on reading the string if the character followed by "beer" isn't EOF (I dont know how to do this though..)? Or is this the wrong mindset?

  6. #6
    Registered User
    Join Date
    Jan 2011
    Posts
    15
    You could fscanf and read each word in the file. You won't encounter any problems...It's pretty straightforward.

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    To use strstr() you will need to loop through the string counting how many occurrences you find in each line. However as stated by revanthb300 the easier method probably would be to get one word at a time from the file and then use strcmp() to compare this word to your key.

    Here is a sample of using the strstr() method:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define MAX 500
     
    int main()
    {
       int count = 0;
       char string[MAX];
       FILE * pf;
       char* pch;
       char key[] = "beer";
       pf = fopen("beer.txt", "r");            /* open file for reading */
     
       while(fgets(string, MAX, pf) != NULL)   /* while there's another line */
       {
          printf("%s", string);
          pch = strstr(string, key);
          while (pch != NULL)
          {
             ++count;
             pch = strstr (pch+1,key);
          }
     
       }
       printf("\n%d\n", count);
       return 0;
    }
    Jim

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Salem View Post
    > FWIW... a much better way of doing this kind of search is to load the entire file as a single string
    No normal person tries to load a file of unknown length into memory only to use each byte of it only once.

    Long before you've actually run out of memory, the start of the file (in memory) is busy being swapped out so you can read the end of the file into memory.
    Horse crap!

    When's the last time you saw a text file bigger than a couple of hundred K?
    I routinely load multi-megabyte files with no problems at all and I run my machines with NO swap file.

    Scanning the file one line at a time is perfectly reasonable, and works just the same regardless of the input file size.
    It's "old think" from MS-DOS days when computer memory was measured in kilobytes... now we play with giga bytes, thousands of times more memory than the computers that spawned this "character by character" or "line by line" mentality you seem to be clinging to...

    I can load a text file with 1 fread() call and can count the words or search for a given word in a 5 to 10 line loop... why the heck would I write more code than I have to just because I don't want to use memory that's sitting empty in the first place?

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Reverse View Post
    Thank you though I can't seem to figure out how to make it loop, I can only get it to count the first occurence if there is one on the line.

    This is what I have now:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAX 500
    int count = 0;
    char string[MAX];
    FILE * pf;
    int main()
    {
        pf = fopen("beer.txt", "r");            /* open file for reading */
        while(fgets(string, MAX, pf) != NULL)   /* while there's another line */
        {
            printf("%s", string);
            if (strstr (string, "beer"))        /* if beer is found in the string */
            count++;                            /* add 1 to count */
        }
        printf("\n%d\n", count);
        return 0;
    }
    I've tried using fgetc, but that doesn't seem to work, I guess I need it to continue on reading the string if the character followed by "beer" isn't EOF (I dont know how to do this though..)? Or is this the wrong mindset?
    With that program structure you're going to need a second loop inside your fgets() loop to scan the line...
    As I said, look up strstr() and pay special attention to it's return value. You should be able to figure it out.

  10. #10
    Registered User
    Join Date
    Nov 2011
    Posts
    3
    Thank you all, I will try to do it in different ways as well to really understand it.

    Nikola

  11. #11
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Reverse View Post
    Thank you all, I will try to do it in different ways as well to really understand it.

    Nikola
    Excellent! Sounds like you've got the right idea... "here's a chance to learn and I'm taking it"...

    If you run into problems with the whole file method I'll be glad to help out.
    Also note that Jim has given you an excellent suggestion using strstr() ... pretty much what I was talking about.
    You can also do this word by word using scanf(" %s"... which stops reading when it hits whitespace.

    Experiment... have fun with it!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. howto open a file for writing several times
    By larne in forum C++ Programming
    Replies: 3
    Last Post: 02-23-2009, 11:35 AM
  2. Replies: 2
    Last Post: 12-02-2007, 05:40 AM
  3. Counting the number of times a loop has run
    By CConfusion in forum C Programming
    Replies: 1
    Last Post: 04-07-2006, 10:23 AM
  4. FILE:string seaching how many times occur
    By Munisamy in forum C Programming
    Replies: 3
    Last Post: 02-26-2005, 02:14 AM