web-dev-qa-db-fra.com

Quelle est la différence entre gets et scanf?

Si le code est

scanf("%s\n",message)  

contre

gets(message)

quelle est la différence? Il semble que les deux reçoivent un message.

9
Shihe Zhang

La différence fondamentale [en référence à votre scénario particulier], 

  • scanf() finit de prendre des informations lorsqu'il rencontre un whitespace, newline ou EOF

  • gets() considère un espace comme faisant partie de la chaîne d'entrée et termine l'entrée lorsque newline ou EOF est rencontré.

Cependant, pour éviter les erreurs de buffer overflow et pour éviter les risques de sécurité, il est plus sûr d’utiliser fgets().

17
Sourav Ghosh

Désambiguïsation: dans le contexte suivant, je considérerais "safe" s'il ne posait pas problème, s'il était utilisé correctement. Et "unsafe" si "unsafetyness" ne peut pas être manipulé.

scanf("%s\n",message)

contre 

gets(message)

Quelle est la différence?

En termes de sécurité, il n'y a pas de différence. Les deux sont lus depuis Standard Input et peuvent très bien déborder message, si l'utilisateur entre plus de données, puis message fournit de la mémoire.

Attendu que scanf() vous permet d’être utilisé en toute sécurité en spécifiant la quantité maximale de données à analyser dans:

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

Avec gets() il est non possible de spécifier le nombre maximal de caractères à lire, c’est pourquoi ce dernier ne doit pas être utilisé !

7
alk

La principale différence est que gets lit jusqu'à ce que EOF ou \n, tandis que scanf("%s") se lit jusqu'à ce qu'aucun espace n'ait été rencontré. scanf fournit également plus d'options de formatage, mais en même temps, la sécurité de type est pire que gets.

Une autre grande différence est que scanf est une fonction C standard, alors que gets a été supprimé de la langue, car elle était à la fois superflue et dangereuse: il n'y avait pas de protection contre les dépassements de mémoire tampon. Cependant, le même défaut de sécurité existe avec scanf, de sorte queaucune de ces deux fonctions ne devrait être utilisée dans le code de production.

Vous devriez toujours utiliser fgets, le standard C lui-même le recommande même, voir C11 K.3.5.4.1

Pratique recommandée  

6 La fonction fgets permet d’écrire correctement programmes pour traiter en toute sécurité les lignes d’entrée trop longues à stocker dans le résultat tableau. En général, cela nécessite que les appelants de gadgets fassent attention à la présence ou l'absence d'un caractère de nouvelle ligne dans le tableau de résultats . Pensez à utiliser fgets (avec tout traitement nécessaire basé sur les caractères New-line) au lieu de gets_s.

(c'est moi qui souligne)

4
Lundin

gets - Lit les caractères de stdin et les stocke sous forme de chaîne. 

scanf - Lit les données de stdin et les stocke selon le format spécifié dans l'instruction scanf comme %d, %f, %s, etc.

4
Shwetha

Il y a plusieurs. La première est que gets () obtiendra uniquement les données de chaîne de caractères. Une autre est que gets () n’obtient qu’une variable à la fois. scanf () est en revanche un outil beaucoup plus souple. Il peut lire plusieurs éléments de différents types de données.

Dans l'exemple que vous avez choisi, il n'y a pas beaucoup de différence.

4
Dinesh

obtient: ->

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

BOGUES: ->

   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;

PUNAISE

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

Dans le cas de scanf, vous avez besoin du format mentionné, contrairement à in. Ainsi, dans gets, vous entrez des caractères, des chaînes, des nombres et des espaces.

Dans le cas de scanf, votre saisie prend fin dès qu’un espace blanc est rencontré.

Mais dans votre exemple, vous utilisez '% s' donc, ni gets() ni scanf() que les chaînes ne sont des pointeurs valides vers des tableaux d'une longueur suffisante pour contenir les caractères que vous leur envoyez. D'où peut facilement provoquer un débordement de tampon.

Astuce: utilisez fgets(), mais cela dépend du cas d'utilisation

2
argentum47

gets () est dangereux, par exemple: char str [1]; gets (str) si vous entrez plus que la longueur, il finira par SIGSEGV . si seulement peut utiliser gets, utilisez malloc comme variable de base.

0
luke's programmer

Le concept selon lequel scanf ne prend pas d'espace est totalement faux. Si vous utilisez cette partie du code, il faudra également un espace blanc:

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

Là où l'utilisation de la nouvelle ligne ne cessera que de prendre des entrées. Cela signifie que si vous appuyez sur entrée seulement, alors il cessera de prendre des entrées. 

Donc, il n'y a pratiquement pas de différence entre scanf et obtient des fonctions. C'est juste un moyen délicat de mise en œuvre. 

0
Anirban Ghosh

scanf() est un outil beaucoup plus flexible alors que gets() n'obtient qu'une variable à la fois. 

0
Kambugu Ismail