Scanf nicht zu überschreiten Pufferüberlauf
Frage
Ich habe einen Puffer und ich will den Benutzer nicht mehr zur Eingabe von Zeichen als der Puffer halten kann (einen Pufferüberlauf zu vermeiden).
Ich bin mit scanf
und haben so gemacht:
char buffer[30] = {'\0'};
scanf("%30s", buffer);
Aber ich weiß, dass ich geschützt bin, wenn der Benutzer mehr als 30. Allerdings tritt, wenn der Benutzer mehr als 30 tritt, wird der Puffer sein null beendet?
Lösung
scanf()
mit einem "% s" Konvertierungsspezifizierer fügt eine abschließende Null-Zeichen in den Puffer.
Aber , sind Sie für 30 Zeichen zu fragen, was wirklich 31 bedeutet, und hat nur Platz für 30. Sie eine maximale Feldbreite von 29 verwendet werden sollen.
char buffer[30] = {'\0'};
scanf("%29s", buffer);
Beachten Sie auch, dass die Konvertierungsspezifizierer "%c"
ziemlich wie "%s"
funktioniert, aber nicht das abschließende Nullzeichen hinzufügen und nicht Ablageraum vom Eingang. Je nachdem, was Sie erwarten, könnte es besser sein als die Verwendung von „% s“.
char buffer[30] = {'\0'};
scanf("%29c", buffer);
buffer[29] = '\0';
Andere Tipps
Von der scanf
Handbuch:
s Findet eine Folge von Nicht-white-space Zeichen; der nächste Zeiger muss ein Zeiger auf char sein, und das Array groß genug sein muss, um nehmen alle die Sequenz und die abschließenden NUL-Zeichen. Das Eingabestring hält an Leerraum oder bei der maximalen Feldbreite, je nachdem welcher Fall zuerst eintritt.
Sie Aufruf UB. Versuchen Sie:
#define str(x) #x
#define xstr(s) str(x)
#define BUFSIZE 30
char buffer[ BUFSIZE + 1 ];
scanf("%" xstr(BUFSIZE) "s", buf);
Um etwas über BUFSIZE
Zeichen Unterdrückungs-Zuordnung ignorieren:
scanf("%" xstr(BUFSIZE) "s%*", buf);
Sie sollten auch prüfen, ob der Benutzer Return / Newline abgeschlossen hat und beenden scanf
wenn er hat:
scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
, und es ist eine gute Übung für die Rückgabewerte zu überprüfen, also:
int rc = scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
und schließlich geprüft, ob die es etwas nach links (wie das Newline und verbrauchen):
if (!feof(stdin))
getchar();
Sie werden einen Pufferüberlauf, weil Sie nicht für das abschließende NUL-Zeichen erlaubt haben. Erklären Sie Ihre Puffer wie folgt aus:
char buffer[31];
und Sie werden in Ordnung sein.