Lokale Variablen in Funktionen definiert w Wenn nicht explizit initialisiert, haben sie einen unbestimmten Wert. Für Zeiger bedeutet das, dass sie auf einen scheinbar zufälligen Ort zeigen. Die Verwendung einer nicht initialisierten Variablen außer der Initialisierung führt zu undefined behavior.
Was hier passiert, ist, dass fgets
den (nicht initialisierten und scheinbar zufälligen) Zeiger verwendet und ihn zum Schreiben in den Speicher verwendet, auf den er zeigt. Dieser Speicher gehört in den meisten Fällen nicht zu Ihnen oder Ihrem Programm und kann sogar andere wichtige Daten überschreiben. Dies kann zu Abstürzen oder anderen seltsamen Verhalten oder Ergebnissen führen.
Die einfachste Lösung ist str
ein Array von Arrays von Zeichen zu machen, wie
#define NUM_OF_STRINGS 2
#define STRING_LENGTH 64
...
char str[NUM_OF_STRINGS][STRING_LENGTH];
...
fgets(str[i], sizeof str[i], stdin);
Sie müssen sicherstellen, dass STRING_LENGTH
oben genug ist, jede Saite einschließlich der Newline und dem String-Terminator zu passen. Im Fall dessen, was ich oben zeige, ist es 64
das bedeutet, dass Sie Zeilen von höchstens 62 Zeichen haben können.
Jetzt wie für das andere Problem, wies ich darauf hin, mit dem ersten Aufruf von fgets
eine leere Zeile zu lesen.
Wenn Sie den Eingang haben
2 2
hello
Der Eingang in einem Puffer im Speicher gespeichert ist, und dann scanf
und fgets
aus diesem Puffer liest.Der Puffer wird mit dem oben Eingang, in etwa so aussehen
+----+----+----+----+----+----+----+----+----+
| 2 | 2 | \n | h | e | l | l | o | \n |
+----+----+----+----+----+----+----+----+----+
Nach dem scanf
Aufruf die beiden Zahlen der Eingangspuffer sieht aus wie
+----+----+----+----+----+----+----+
| \n | h | e | l | l | o | \n |
+----+----+----+----+----+----+----+
So lesen, was der erste Aufruf an fgets
in der Schleife wird sehen, ist der Newline. So liest es, dass Newline und dann ist es fertig, die Zeichenfolge "hello\n"
im Puffer für die zweiten Anruf an fgets
verlassen.
Es gibt einige Möglichkeiten, dieses Problem zu lösen. Dasjenige, das ich persönlich bevorzuge, ist, fgets
universell zu verwenden, um Linien zu lesen, und wenn Sie eine einfache Analyse der Linie benötigen, dann verwenden Sie sscanf
(beachten Sie die führende s
, auch bitte see here for a good reference of all scanf
variants), um dies zu tun.
Eine andere Möglichkeit besteht darin, einfach Zeichen von der Eingabe zu lesen und sie zu verwerfen. Wenn Sie einen Zeilenumbruch lesen, stoppen Sie die Schleife und fahren Sie mit dem Rest des Programms fort.
Verwenden Sie fgets() und dann strtok(), um die Zeichenfolge aufzuteilen. –
Was Ihr * aktuelles * Problem betrifft, den Absturz, den Sie bekommen, denken Sie jetzt ein wenig nach. Du deklarierst ein Array von Zeigern auf 'char', aber du machst diese Zeiger niemals * irgendwo *. –
Hallo Matt. Danke für Ihre Antwort. Ich bin neu in c. Ich weiß nicht, wie man strtok() benutzt. Ich werde es jetzt nachschlagen. – chrisgjh