简体   繁体   中英

What's the difference between gets and scanf?

If the code is

scanf("%s\n",message)  

vs

gets(message)

what's the difference?It seems that both of them get input to message.

The basic difference [in reference to your particular scenario],

  • scanf() ends taking input upon encountering a whitespace , newline or EOF

  • gets() considers a whitespace as a part of the input string and ends the input upon encountering newline or EOF .

However, to avoid buffer overflow errors and to avoid security risks, its safer to use fgets() .

Disambiguation: In the following context I'd consider " safe " if not leading to trouble when correctly used. And " unsafe " if the "unsafetyness" cannot be maneuvered around.

 scanf("%s\\n",message)

vs

gets(message)

What's the difference?

In terms of safety there is no difference, both read in from Standard Input and might very well overflow message , if the user enters more data then message provides memory for.

Whereas scanf() allows you to be used safely by specifying the maximum amount of data to be scanned in:

char message[42];

...

scanf("%41s", message); /* Only read in one few then the buffer (messega here) 
                           provides as one byte is necessary to store the 
                           C-"string"'s 0-terminator. */

With gets() it is not possible to specify the maximum number of characters be read in, that's why the latter shall not be used !

The main difference is that gets reads until EOF or \\n , while scanf("%s") reads until any whitespace has been encountered. scanf also provides more formatting options, but at the same time it has worse type safety than gets .

Another big difference is that scanf is a standard C function, while gets has been removed from the language, since it was both superfluous and dangerous: there was no protection against buffer overruns. The very same security flaw exists with scanf however, so neither of those two functions should be used in production code .

You should always use fgets , the C standard itself even recommends this, see C11 K.3.5.4.1

Recommended practice

6 The fgets function allows properly-written programs to safely process input lines too long to store in the result array. In general this requires that callers of fgets pay attention to the presence or absence of a new-line character in the result array. Consider using fgets (along with any needed processing based on new-line characters) instead of gets_s.

(emphasis mine)

gets - Reads characters from stdin and stores them as a string.

scanf - Reads data from stdin and stores them according to the format specified int the scanf statement like %d , %f , %s , etc.

There are several. One is that gets() will only get character string data. Another is that gets() will get only one variable at a time. scanf() on the other hand is a much, much more flexible tool. It can read multiple items of different data types.

In the particular example you have picked, there is not much of a difference.

gets:->

gets() reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF, which it replaces with a null byte ( '\\0' ).

BUGS:->

Never use gets() . Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.

scanf:->

The scanf() function reads input from the standard input stream stdin;

BUG:->

Some times scanf makes boundary problems when deals with array and string concepts.

In case of scanf you need that format mentioned, unlike in gets. So in gets you enter charecters, strings, numbers and spaces.

In case of scanf , you input ends as soon as a white-space is encountered.

But then in your example you are using '%s' so, neither gets() nor scanf() that the strings are valid pointers to arrays of sufficient length to hold the characters you are sending to them. Hence can easily cause an buffer overflow.

Tip: use fgets() , but that all depends on the use case

The concept that scanf does not take white space is completely wrong. If you use this part of code it will take white white space also :

#include<stdio.h>
int main()
{
char name[25];  
printf("Enter your name :\n");
scanf("%[^\n]s",name);
printf("%s",name);
return 0;
}

Where the use of new line will only stop taking input. That means if you press enter only then it will stop taking inputs.

So, there is basically no difference between scanf and gets functions. It is just a tricky way of implementation.

scanf()是一种更灵活的工具,而gets()只能获取一个变量。

gets() is unsafe, for example: char str[1]; gets(str) if you input more then the length, it will end with SIGSEGV. if only can use gets, use malloc as the base variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM