gets()

Discussion in 'Mac Programming' started by farmerdoug, Oct 28, 2011.

  1. farmerdoug macrumors 6502a

    Joined:
    Sep 16, 2008
    #1
    Running code with gets from the command line. I get a warning that gets is unsafe. Did I unknowingly switch to the hated microsoft? What's with the warning? Should I turn it off? How? or reprogram with scanf?
     
  2. cbougher macrumors member

    Joined:
    Oct 19, 2006
    Location:
    Atlanta, GA
    #2
    From Wikipedia

    gets is a function in the C standard library, declared in the header file stdio.h, that reads a line from the standard input and stores it in a buffer provided by the caller.
    Use of gets is strongly discouraged. It is left in the C89 and C99 standards for backward compatibility (but officially deprecated in late revisions of C99). It is removed from the C1X draft[1] and instead a range checking alternative gets_s is introduced.[2] Many development tools such as GNU ld emit warnings when code using gets is linked.​

    Wiki
     
  3. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #3
    gets() has no way to specify the maximum length of the buffer it reads into. That means long lines of input can and will overflow the buffer. You have no control over the length of an input line (i.e. where the newline occurs).

    The safer replacement is fgets(), which has a max length (refer to its man page).

    scanf() is not at all similar to gets() or fgets().

    I think this has come up before in your posts, and the previous recommendation was also to use fgets().
     
  4. RLesko macrumors member

    Joined:
    Jul 21, 2011
    #4
    The issue with gets() is that it will keep reading characters until a newline character is found. If you are clever enough in what you enter to overflow the buffer, the function/stack pointers may be adjusted to different areas and cause certain code to be executed.
     
  5. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #5
    The previous discussion was not about fgets and the command line. I tried fgets in various ways; it doesn't work as well as gets.

    Code:
    a = 'Y';
    date = (char*) calloc(10, sizeof(char));
    do
        {
        printf("input date xx/xx/xx\n");
        fgets(date,8,stdin);
        fflush(stdin);
        if(strlen(date) == 8)
            {
            printf("Is this the right date Y or N? %s\n", date);
            a = getc(stdin);
            fflush(stdin);
            }
            else 
            {
            printf("wrong format for date\n");
            a = 'N';    
            }
    
        }
    while((a  == 'N') || (a == 'n'));
    


    ----------

    switched to scanf. All okay.
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    You should read the man page for gets(). It's the same man page as fgets(). There is a difference in how each function works, specifically in what's returned in the buffer. I urge you to actually read the man page so you know exactly what each one does, and so you know to look there first in the future.

    Removing a newline from the end of a C string isn't hard. Write a function:
    Code:
    char * safe_gets( char * str, int size );
    
    It always reads from stdin, so there's no FILE* arg. It internally calls fgets(), then removes any newline. That gives a potential ambiguity, but since you don't seem to care (i.e. the fact you're using gets() at all), I don't see the harm. The advantage is that safe_gets() won't overrun the buffer if a newline doesn't appear after size chars have been read.

    Having a function also means you can use it again in the future, as it seems likely this issue will come up again. A little forethought can save a lot of debugging and afterthought.
     
  7. Sander macrumors 6502

    Joined:
    Apr 24, 2008
    #7
    Your question was how to get rid of the warning you get when using gets(). The answer was that you should consider switching to fgets(). How does fgets() not works as well as gets()?
     

Share This Page