scanf ne pas dépasser dépassement de tampon
Question
J'ai un tampon et je ne veux pas l'utilisateur d'entrer plus de caractères que le tampon peut contenir (pour éviter un dépassement de mémoire tampon).
J'utilise scanf
et ai fait comme ceci:
char buffer[30] = {'\0'};
scanf("%30s", buffer);
Cependant, je sais que je suis protégé si l'utilisateur entre plus de 30. Toutefois, si l'utilisateur entre plus de 30 ans, sera le tampon NULLE fin?
La solution
scanf()
avec un spécificateur de conversion "% s" ajoute un caractère nul final de la mémoire tampon.
Mais , vous demandez 30 caractères, ce qui signifie vraiment 31 et seulement un espace pour 30. Vous devez utiliser une largeur de champ maximum de 29.
char buffer[30] = {'\0'};
scanf("%29s", buffer);
Notez également que les indicateurs de conversion "%c"
fonctionne à peu près comme "%s"
, mais ne pas ajouter le caractère nul et ne rejette pas l'espace de l'entrée. Selon ce que vous attendez, il pourrait être mieux que d'utiliser « % s ».
char buffer[30] = {'\0'};
scanf("%29c", buffer);
buffer[29] = '\0';
Autres conseils
Dans le manuel de scanf
:
s correspond à une séquence de des caractères non-espace blanc; le suivant aiguille doit être un pointeur vers un char, et le tableau doit être assez grand pour accepter la totalité de la séquence et la terminaison de caractère NUL. le chaîne d'entrée arrête à un espace blanc ou à la largeur maximale du champ, selon le premier terme.
Vous invoquez UB. Essayez:
#define str(x) #x
#define xstr(s) str(x)
#define BUFSIZE 30
char buffer[ BUFSIZE + 1 ];
scanf("%" xstr(BUFSIZE) "s", buf);
Pour ignorer quoi que ce soit au-delà des caractères BUFSIZE
supprimer l'affectation:
scanf("%" xstr(BUFSIZE) "s%*", buf);
Vous devriez également vérifier si l'utilisateur est entré retour / saut de ligne et de mettre fin à scanf
s'il a:
scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
et il est bon de vérifier les valeurs de retour, donc:
int rc = scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
et enfin, vérifier s'il y a quelque chose de la gauche (comme la nouvelle ligne, et de le consommer):
if (!feof(stdin))
getchar();
Vous aurez un dépassement de mémoire tampon parce que vous ne l'avez pas permis de mettre fin à caractère NUL. Déclarez votre tampon comme ceci:
char buffer[31];
et vous serez très bien.