Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

farmerdoug

macrumors 6502a
Original poster
Sep 16, 2008
541
0
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?
 

cbougher

macrumors member
Oct 19, 2006
34
0
Atlanta, GA
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
 

chown33

Moderator
Staff member
Aug 9, 2009
10,751
8,425
A sea of green
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?

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().
 

RLesko

macrumors member
Jul 21, 2011
93
1
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.
 

farmerdoug

macrumors 6502a
Original poster
Sep 16, 2008
541
0
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.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,751
8,425
A sea of green
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.
 

Sander

macrumors 6502a
Apr 24, 2008
521
67
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.

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()?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.