В чем разница между gets и scanf?

Если код

scanf("%sn",message)  

vs

gets(message)

в чем разница?Кажется, что оба они получают вход в сообщение.

10 ответов


основное различие [в отношении конкретного сценария],

  • scanf() заканчивается ввод при встрече с whitespace, newline или EOF

  • gets() рассматривает пробелы как часть входной строки и завершает ввод при встрече newline или EOF.

однако, чтобы избежать переполнение буфера ошибки и избежать рисков для безопасности, свой безопасный для использования fgets().


Disambiguation: в следующем контексте я бы рассмотрел "безопасное " если не приводит к неприятностям при правильном использовании. И"небезопасных" если "unsafetyness" не может быть маневрировал вокруг.

scanf("%s\n",message)

vs

gets(message)

в чем разница?

С точки зрения безопасности нет никакой разницы, как читать с Standard Input и вполне может переполниться message, если пользователь вводит больше данных, то messageобеспечивает память для.

, тогда как scanf() позволяет безопасно использовать, указав максимальный объем данных для сканирования в:

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. */

С gets() это не можно указать максимальное количество символов для чтения, поэтому последний не используется!


Существует несколько. Один из них заключается в том, что gets() будет получать только данные символьной строки. Другое дело, что gets () будет получать только одну переменную за раз. scanf (), с другой стороны, является гораздо более гибким инструментом. Он может считывать несколько элементов различных типов данных.

в конкретном примере, который вы выбрали, нет большой разницы.


главное отличие в том, что gets читает до EOF или \n, а scanf("%s") читает, пока не будет обнаружено пробелов. scanf также предоставляет больше возможностей для форматирования, но в то же время он хуже по безопасности, чем gets.

еще одна большая разница в том, что scanf является стандартной функцией C, в то время как gets был удален из языка, так как он был излишним и опасным: не было защиты от переполнения буфера. Тот же однако в scanf существует недостаток безопасности, поэтому ни одна из этих двух функций не должна использоваться в производственном коде.

вы всегда должны использовать fgets, сам стандарт C даже рекомендует это, см. C11 K. 3.5.4.1

рекомендуется

6 функция fgets позволяет правильно писать программы для безопасной обработки входных строк слишком долго для хранения в результате матрица. В общем это требует на что обращают внимание абоненты fgets наличие или отсутствие символа новой строки в массиве результатов. рассмотрим с помощью помощью fgets (вместе с любой необходимой обработкой основанной на символы новой строки) вместо gets_s.

(выделено мной)


gets - считывает символы из stdin и сохраняет их в виде строки.

scanf - считывает данные из stdin и сохраняет их в соответствии с форматом, указанным в scanf оператор like %d, %f, %s, etc.


получает:->

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

ошибки:->

   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;

ошибка

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

в случае scanf вам нужен этот формат, упомянутый, в отличие от gets. Так gets вы вводите charecters, строки, числа и пробелы.

в случае scanf, ввод заканчивается, как только встречается пробел.

но тогда в вашем примере вы используете "%s", поэтому ни gets(), ни scanf() что строки являются допустимыми указателями на массивы достаточной длины для хранения символов, которые вы отправляете им. Следовательно, может легко вызвать буфер переполнение.

совет: используйте fgets(), но это все зависит от варианта использования


концепция, что scanf не занимает пустое пространство, полностью неверна. Если вы используете эту часть кода, она также займет Белый пробел:

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

где использование новой строки остановит только ввод. Это означает, что если вы нажмете enter только тогда он перестанет принимать входы.

таким образом, в основном нет разницы между scanf и функциями gets. Это просто хитрый способ осуществления.


gets () небезопасно, например: char str[1]; gets(str) если вы введете больше, чем длина, она закончится SIGSEGV. если только можно использовать gets, используйте malloc в качестве базовой переменной.


scanf() гораздо более гибкий инструмент, в то время как gets() получает только одну переменную за раз.