Sie sollten nie Verwendung gets
(oder scanf
mit unbeschränkter Stringgröße) da, dass Sie überläuft bis puffern öffnet. Verwenden Sie die fgets
mit einem stdin
Griff, da es Ihnen, die Daten beschränken kann, die in Ihrem Puffer platziert werden.
Hier ist ein kleiner Ausschnitt I für Zeile Eingabe vom Benutzer verwenden:
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
Dies ermöglicht es mir, um die maximale Größe gesetzt ist, wird erkennen, ob zu viele Daten auf der Zeile eingegeben werden, und wird den Rest bündig von der Linie, so dass es die nächste Eingabeoperation nicht beeinflusst.
Sie können es testen mit so etwas wie:
// Test program for getLine().
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
nicht die Systembibliotheken, die scanf implementieren verhindern einen Überlauf des Befehls (ich verstehe, dass innerhalb des Programms, wenn der Entwickler die Eingabe nicht überprüft hat, könnte es einen Überlauf geben, aber die Systembibliothek ist sicher oder?). – Marm0t
Nein, wenn Sie "scanf" ("% s") in einen 20-Byte-Puffer und der Benutzer eine 40-Byte-Zeile eingibt, werden Sie abgespritzt. Der ganze Punkt von 'scanf' ist scan-formatiert und es gibt wenig mehr _unformatted_ als Benutzereingabe :-) – paxdiablo
@ Marm0t - Denken Sie auf diese Weise durch die Betrachtung der folgenden Frage: Wie kann die Implementierung einen Überlauf verhindern, wenn alles es ist ein Zeiger auf eine Scheibe des Gedächtnisses (typecasted als char *) 'ohne irgendeinen Parameter, der der Implementierung über die Größe des Zielpuffers sagt'? –