Thread: read more chars than the buffer side and detect while preventing overflow

  1. #1
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694

    read more chars than the buffer side and detect while preventing overflow

    I want to check is the user inputs a word that has more than 10 characters.If he does,let's say we exit the program.

    This not my code,so do not comment the global variables etc...

    Code:
    #include <assert.h>
    #include <string.h>
    #include <stdio.h>
    #include <wchar.h>
    #include <locale.h>
    
    typedef struct {
        wchar_t term[10];
        int freq;
    } word_t;
    
    /* global array of words */
    word_t words[5000];
    int n_words = 0;
    
    int find_word(wchar_t s[]) {
        int i;
        for (i=0; i < n_words; i++)
            if (wcsncmp(s, words[i].term,10) == 0)
                return i;
        return -1;
    }
    
    void add_word(wchar_t s[]) {
        assert(wcslen(s) <= 10);
        wcsncpy(words[n_words].term, s,10);
        words[n_words].freq = 1;
        n_words++;
    }
    
    int main(void) {
        char myStr[11];
        wchar_t s[11];
        setlocale(LC_CTYPE,"UTF-8");
        printf("Please type a word with 10 characters at most\n");
        /*could use fgetws and wprintf instead*/
        while ((fgets(myStr,10,stdin)!= NULL)) {
            if(strlen(myStr)>10)
            {
                 printf("Word with more than 10 characters detected, so exiting...\n");
                 return -1;
            }
            mbstowcs(s,myStr,strlen(myStr));
            int i = find_word(s);
            if (i == -1)
            {
                add_word(s);
                printf("1: %s\n", myStr);
            }
            else
            {
                words[i].freq++;
                printf("%d: %s\n",words[i].freq ,myStr);
            }
            printf("Please type a word with 10 characters at most\n");
        }
        return 0;
    }
    When the user enters a word larger than 10 characters,then this word will split at the 10-nth character because of the fgets (with scanf and %10 it will be the same i guess),so it will re-loop without getting anything anything from input ,reading the rest of the word (if it is less than 20 characters).
    I thought to go dynamically and ask the user for the size of the buffer but then again i have to make sure that the user will not overflow my little buffer.
    Also an idea of declaring a larger array before, breaks my heart because it is such a waste of memory.
    So maybe i could look at the end of the loop and determine if there is some letters left in the stdin buffer.If so this means that the user typed a bigger word than 10 characters.
    Any ideas?

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Depending on how large the array, I wouldn't worry. Unless this is some embedded or otherwise limited-resource system, 500-1k bytes is no biggie (I often use BUFSIZ, it's declared in stdio.h).

    Perhaps you could just use getchar() in a loop, check for newline/EOF yourself, and check your 10 char limit.

  3. #3
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Quote Originally Posted by anduril462 View Post
    Depending on how large the array, I wouldn't worry. Unless this is some embedded or otherwise limited-resource system, 500-1k bytes is no biggie (I often use BUFSIZ, it's declared in stdio.h).
    Perhaps you could just use getchar() in a loop, check for newline/EOF yourself, and check your 10 char limit.
    Exactly what i just thought it thanks

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    fgets will never overflow a buffer on purpose, you the coder have to pass in bad arguments to make it happen, so the check does not even make sense right now.

    I don't actually have a better answer for you. You already know that the word will break off. I'm not seeing the problem with it though. I mean, the same word will break off in the same place. Take any sufficiently long word, like, mentholated-cigarettes. Mentholat ed-cigare ttes ... It would occur as frequently as the entire actual word.

  5. #5
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Maybe checking the string for the '\n' character after the fgets
    Fact - Beethoven wrote his first symphony in C

  6. #6
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by Click_here View Post
    Maybe checking the string for the '\n' character after the fgets
    This is exactly how you check whether fgets has read up to it's limit and there's more left in the buffer, and the very reason fgets leaves the newline in the buffer at all.

    Quote Originally Posted by std10093
    When the user enters a word larger than 10 characters,then this word will split at the 10-nth character because of the fgets (with scanf and %10 it will be the same i guess)
    scanf with a %10s differs from fgets with a limit of 10 in two ways:
    1. scanf("%10s",...) will stop at the first space encountered.
    2. fgets(buf,10,...) will read up to 9 chars and then zero-terminate, whereas scanf("%10s",...) will read up to 10 chars and then zero-terminate.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Preventing overflow
    By 843 in forum C++ Programming
    Replies: 7
    Last Post: 03-18-2011, 11:18 AM
  2. buffer overflow
    By cpp_is_fun in forum C Programming
    Replies: 2
    Last Post: 10-24-2006, 11:04 PM
  3. detect variable overflow
    By surdy in forum C Programming
    Replies: 9
    Last Post: 05-13-2004, 12:49 PM
  4. buffer overflow problems
    By neandrake in forum C++ Programming
    Replies: 13
    Last Post: 12-04-2003, 08:02 AM