Thread: warnings & error messages

  1. #1
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242

    warnings & error messages

    Hi all. I am stumped by the warnings and errors for the "countwords" function.

    Code:
    // wordcount.c: count the number of occurrences of every word in a text file
    // 4 functions: openfile, countwords, sort, display
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define FILENAMELENGTH 30
    #define SUCCESS 1
    #define FAILURE 0
    
    FILE *file;
    
    int openfile(char *filename);
    void countwords(void);
    void sort(char *filename);
    void display(char *filename);
    
    int main(void)
    {
        int result;
        char filename[FILENAMELENGTH];
    
        do
        {
            printf("Enter file to open: ");
            fgets(filename, FILENAMELENGTH, stdin);
            filename[strlen(filename) - 1] = '\0';
        } while((result = openfile(filename)) == FAILURE);
    
        countwords();
        sort(filename);
        display(filename);
    
        return 0;
    }
    
    int openfile(char *filename)
    {
        if((file = fopen(filename, "r")) == NULL)
            return FAILURE;
        else
        {
            printf("%s opened successfully", filename);
            return SUCCESS;
        }
    }
    
    void countwords(void)
    {
        #define WORDLENGTH 30
    
        char buffer[WORDLENGTH];
        int c, count;
    
        struct word
        {
            char *word;
            int wordcount = 0;
        } array[500];
    
        while((c = fgetc(file)) != EOF)
        {
            if((c != '.') && (c != ',') && (c != '!') && (c != "") && (c != ':'))     //if c is not a space or punctuation, add c to buffer[]
            {
                buffer[count] = c;
                count++;
            }
    
            else
            {
                buffer[count++] = '\n';     // if c is a space or punctuation, add terminator to create string
                array[count].word = malloc((count) * sizeof(char));     // allocate memory for string
                *array[count].word = buffer[count];    // assign string to pointer in structure
                array[count].wordcount++;       // increment counter for word
            }
        }
    }
    
    void sort(char *filename)
    {
    
    }
    
    void display(char *filename)
    {
    
    }
    Code:
    |In function ‘countwords’:|
    59|error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token|
    64|warning: comparison between pointer and integer [enabled by default]|
    64|warning: comparison with string literal results in unspecified behaviour [-Waddress]|
    75|error: ‘struct word’ has no member named ‘wordcount’|
    ||=== Build finished: 2 errors, 2 warnings ===|
    1. What does it mean by expected ; etc in line 59? I can't see any missing punctuation.
    2. For line 64, fgetc returns an integer, and I am comparing it with characters(which are integers), so why does it mention pointer?
    3. Also, for line 65, "string literal" means "", right? When I use ' ', I get an error message "empty character constant". I just want to compare c to empty white space.
    4. There is a "wordcount" member in the struct, so why the error message?

    Thanks in advance.
    Last edited by cfanatic; 07-31-2012 at 06:51 AM.
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  2. #2
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    1. You cannot initialize struct members in line 59. "int wordcount = 0;" is invalid.
    2. You are comparing an integer with a string, which is a pointer to its first element.
    3. There is no error on line 65.
    4. This is caused by the first error.

    Edit for question 3: what do you mean by "empty white space"? White space is not empty. White space can be a tab, space, newline, vertical tab, etc. You can use isspace(c) (and #include <ctype.h>) to see if c is a whitespace character, or isblank(c) to see if c is space or tab.
    Last edited by christop; 07-31-2012 at 07:27 AM.

  3. #3
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    Quote Originally Posted by christop View Post
    1. You cannot initialize struct members in line 59. "int wordcount = 0;" is invalid.
    2. You are comparing an integer with a string, which is a pointer to its first element.
    3. There is no error on line 65.
    4. This is caused by the first error.

    Edit for question 3: what do you mean by "empty white space"? White space is not empty. White space can be a tab, space, newline, vertical tab, etc. You can use isspace(c) (and #include <ctype.h>) to see if c is a whitespace character, or isblank(c) to see if c is space or tab.
    1. Ok.
    2. Are you saying c is the integer, and '.', '!' etc are pointers? Or the other way around? I want to count words, so I know that punctuations do not form words.
    3. Line 64. Say there is the sentence "How now brown cow". I want to compare c with the space after the "How". If c is a space, then I know that the characters up to the space form a word. Then I want to add a '\0' at the end of How and save it to the pointer in the array of structs.

    Thanks.
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  4. #4
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    All christop said are correct.The problem with line 64 is
    Code:
    (c!=" ")
    Try this
    [code]
    (c!=' ')
    [\code]
    the reason is point 2 that christop mentioned

  5. #5
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    • Code:
      filename[strlen(filename) - 1] = '\0';
      To be pedantic, this isn't necessarily the best way to remove the newline character. If the user enters a file name that's FILENAMESIZE characters long, you could be cutting off characters.
    • You should declare structs at the top of your code/in a header file, instead of in the middle of a function.
    • You aren't freeing memory that you allocate.
    • Code:
      while((c = fgetc(file)) != EOF)
      It's probably best to read the whole file (or at least large chunks) into a buffer, and then step through the buffer once it's in memory. This way, you're ensuring that file I/O is as infrequent as possible (as it's much slower than memory access).
    • If you have more than 500 words, your program will not catch the array overrun and will likely crash.
    • Code:
      (c != '.') && (c != ',') && (c != '!') && (c != "") && (c != ':'
      You could use the routines from ctype.h to simplify this for readability and efficiency.
    • Code:
      *array[count].word = buffer[count];
      Are you trying to copy the word from buffer into the struct? If so, you need to use strncpy and then zero out the buffer before you try to copy again.

  6. #6
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    Quote Originally Posted by std10093 View Post
    All christop said are correct.The problem with line 64 is
    Code:
    (c!=" ")
    Try this
    [code]
    (c!=' ')
    [\code]
    the reason is point 2 that christop mentioned
    You mean like this?
    Code:
    if((c != '.') && (c != ',') && (c != '!') && (c != '') && (c != ':') && (c != ' '))
    That was what I tried first, and it keeps giving me an "empty character constant" error. That's why I tried to use " ".
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  7. #7
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    Quote Originally Posted by memcpy View Post
    • Code:
      filename[strlen(filename) - 1] = '\0';
      To be pedantic, this isn't necessarily the best way to remove the newline character. If the user enters a file name that's FILENAMESIZE characters long, you could be cutting off characters.
    Yes I know. This particular exercise is for me to practice using functions and passing pointers to functions. That's why I don't build in checks for everything. My test file name is "test.txt", so I know I will never hit this problem. I would definitely build checks for serious programs.
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by cfanatic View Post
    You mean like this?
    Code:
    if((c != '.') && (c != ',') && (c != '!') && (c != '') && (c != ':') && (c != ' '))
    That was what I tried first, and it keeps giving me an "empty character constant" error. That's why I tried to use " ".
    Because the 4th comparison has nothing between the ''. Compare:
    Code:
    (c != '')
    and
    Code:
    (c != ' ')
    Notice the latter has an actual space character between the 'single quotes', comparing the variable c to the space character. There are a few differences when you use the "double quotes":

    1. Single quotes are for a single character literal (an integral/integer value). They can be compared to variables of type char.
    2. Double quotes are for string literals, a sequence of one or more characters, ending with a null character. It's type is "pointer to char", and thus can't be compared to a variable of type char. You can only compare string literals with strcmp and friends.
    3. Empty single quotes are invalid, since there is no character literal contained within. The null character, if that's what you want, is expressed as '\0'. For a space character, you must put a space between the two quote marks.
    4. Empty double quotes are valid. They refer to a string literal with just one character, the null terminator, which is implied at the end of every string literal in C. For example "123" actually has 4 characters, the three digits and a null.

  9. #9
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    Thanks for the replies, no more warnings or errors. Now to start on working on memcpy's post.

    Code:
    // wordcount.c: count the number of occurrences of every word in a text file
    // 4 functions: openfile, countwords, sort, display
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define FILENAMELENGTH 30
    #define SUCCESS 1
    #define FAILURE 0
    
    FILE *file;
    
    struct word
        {
            char *word;
            int wordcount;
        } array[500];
    
    int openfile(char *filename);
    void countwords(void);
    void sort(char *filename);
    void display(char *filename);
    
    int main(void)
    {
        int result;
        char filename[FILENAMELENGTH];
    
        do
        {
            printf("Enter file to open: ");
            fgets(filename, FILENAMELENGTH, stdin);
            filename[strlen(filename) - 1] = '\0';
        } while((result = openfile(filename)) == FAILURE);
    
        countwords();
        sort(filename);
        display(filename);
    
        return 0;
    }
    
    int openfile(char *filename)
    {
        if((file = fopen(filename, "r")) == NULL)
            return FAILURE;
        else
        {
            printf("%s opened successfully", filename);
            return SUCCESS;
        }
    }
    
    void countwords(void)
    {
        #define WORDLENGTH 30
    
        char buffer[WORDLENGTH];
        int c, count;
    
    
    
        while((c = fgetc(file)) != EOF)
        {
            if((c != '.') && (c != ',') && (c != '!') && (c != ' ') && (c != ':'))     //if c is not a space or punctuation, add c to buffer[]
            {
                buffer[count] = c;
                count++;
            }
    
            else
            {
                buffer[count++] = '\n';     // if c is a space or punctuation, add terminator to create string
                array[count].word = malloc((count) * sizeof(char));     // allocate memory for string
                *array[count].word = buffer[count];    // assign string to pointer in structure
                array[count].wordcount++;       // increment counter for word
            }
        }
    }
    
    void sort(char *filename)
    {
    
    }
    
    void display(char *filename)
    {
    
    }
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  10. #10
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    In your "countwords()" function, "count" is uninitialized. Therefore, there's no guarantee you'll be storing the characters in the appropriate location.

  11. #11
    Registered User
    Join Date
    Jul 2012
    Posts
    51
    Since you're using string.h, why not use strtok() with fgets()?

    A suggestion, you might want to work on each problem seperately? Once you get working code that you understand, it should be easy to write/merge code that will work in your main program? For example, work on splitting a test string by words, then work on counting the total number of words, and so on.

    Code:
    int main (void)
    {
        char test_str[] = "How now brown cow.";
        /* your code */
    }

  12. #12
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    So now everything works ok?

  13. #13
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    Quote Originally Posted by memcpy View Post
    • Code:
      *array[count].word = buffer[count];
      Are you trying to copy the word from buffer into the struct? If so, you need to use strncpy and then zero out the buffer before you try to copy again.
    Yes I am. Do I absolutely need to use strncpy() for this to work? I would like to get some practice copying to structures using pointers. Here is the code, but it just prints out blanks, instead of the individual words. Is this because I need to use strncpy()?

    Code:
    // wordcount.c: count the number of occurrences of every word in a text file
    // 4 functions: openfile, countwords, sort, display
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define FILENAMELENGTH 30
    #define ARRAYSIZE 1000
    #define SUCCESS 1
    #define FAILURE 0
    
    FILE *file;
    
    struct word
        {
            char *word;
            int wordcount;
        } array[ARRAYSIZE];
    
    int openfile(char *filename);
    void countwords(void);
    void sort(char *filename);
    void display(char *filename);
    
    int main(void)
    {
        int result;
        char filename[FILENAMELENGTH];
    
        do
        {
            printf("Enter file to open: ");
            fgets(filename, FILENAMELENGTH, stdin);
            filename[strlen(filename) - 1] = '\0';
        } while((result = openfile(filename)) == FAILURE);
    
        countwords();
    //    sort(filename);
    //    display(filename);
    
        return 0;
    }
    
    int openfile(char *filename)
    {
        if((file = fopen(filename, "r")) == NULL)
            return FAILURE;
        else
        {
            printf("%s opened successfully", filename);
            return SUCCESS;
        }
    }
    
    void countwords(void)
    {
        #define WORDLENGTH 30
    
        char buffer[WORDLENGTH];
        int c, buffercount = 0, arraycount = 0, arraycount1;
    
        while((c = fgetc(file)) != EOF)
        {
            if((c != '.') && (c != ',') && (c != '!') && (c != ' ') && (c != ':'))     //if c is not a space or punctuation, add c to buffer[]
            {
                buffer[buffercount] = c;
                buffercount++;
            }
    
            else
            {
                buffer[buffercount] = '\n';     // if c is a space or punctuation, add terminator to create string
                array[arraycount].word = malloc((buffercount) * sizeof(char));     // allocate memory for string
                *array[arraycount].word = buffer[buffercount];    // assign string to pointer in structure
                array[arraycount].wordcount++;       // increment counter for word
                arraycount1 = arraycount;    // arraycount1 keeps a record of the number of arrays that contain a word
                arraycount++;       // increment the word array to accept next word
                buffercount = 0;    // reset buffer starting location to 0
            }
        }
    
        for(arraycount = 0; arraycount < arraycount1; arraycount++)
        {
            printf("%s\n", array[arraycount].word);
        }
    }
    Last edited by cfanatic; 08-01-2012 at 07:59 AM.
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  14. #14
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    strcpy and strncpy are two very useful functions.Try to learn them because what you are trying to do will have no use in bigger programs(it is not convenient )

  15. #15
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Below i created a simple example in order to understand how strcpy works.

    Code:
    #include <stdio.h>
     
    int main(void)
    {
        char name[8]= "Samaras";
        char destName[8];
        printf("My name is %s\n",name);
        strcpy(destName,name);
        printf("My name is %s and the data of destName is %s\n",name,destName);
        return 0;
    }
    and the output is

    Code:
    My name is Samaras
    My name is Samaras and the data of destName is Samaras
    You can see at this link about these functions strcpy - String.h - C - C++ Computing Reference with Worked Examples.strncpy adds to the destination terminating nulls if the length is not equal

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with error messages
    By ashleyd in forum C++ Programming
    Replies: 2
    Last Post: 10-30-2011, 12:59 PM
  2. MANY MANY error messages
    By vrek in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2007, 10:58 PM
  3. Error Messages
    By applescruff in forum C++ Programming
    Replies: 3
    Last Post: 01-25-2005, 10:47 AM
  4. Different error messages...
    By EvBladeRunnervE in forum Networking/Device Communication
    Replies: 2
    Last Post: 03-29-2004, 08:01 PM
  5. need help with error messages
    By Shy_girl_311 in forum C++ Programming
    Replies: 0
    Last Post: 12-01-2001, 02:33 PM