web-dev-qa-db-fra.com

Lire une chaîne avec scanf

Je suis un peu confus à propos de quelque chose. J'avais l'impression que la bonne façon de lire une chaîne en C avec scanf() allait dans le sens de

(peu importe l'éventuel dépassement de tampon, ce n'est qu'un exemple simple)

char string[256];
scanf( "%s" , string );

Cependant, ce qui suit semble fonctionner aussi,

scanf( "%s" , &string );

Est-ce juste mon compilateur (gcc), un pur hasard ou autre chose?

132
abeln

Un tableau "se décompose" en un pointeur sur son premier élément, donc scanf("%s", string) est équivalent à scanf("%s", &string[0]). Par contre, scanf("%s", &string) passe un pointeur sur char[256], mais il pointe au même endroit.

Ensuite, scanf, lors du traitement de la fin de sa liste d'arguments, tentera d'extraire un char *. C’est la bonne chose lorsque vous êtes passé dans string ou &string[0], mais lorsque vous êtes passé dans &string, vous dépendez de quelque chose que la norme de langage ne garantit pas, à savoir que les pointeurs &string et &string[0] - des pointeurs sur des objets de types et de tailles différents qui commencent au même endroit - sont représentés de la même manière.

Je ne crois pas avoir jamais rencontré un système sur lequel cela ne fonctionne pas et, en pratique, vous êtes probablement en sécurité. Néanmoins, c'est faux, et cela pourrait échouer sur certaines plates-formes. (Exemple hypothétique: une implémentation "de débogage" qui inclut des informations de type avec chaque pointeur. I pensez l'implémentation C sur Symbol "Machines LISP" a fait quelque chose comme ça.)

128
Gareth McCaughan