Wie liest man die Standardeingabe in eine String-Variable bis EOF in C?

8

Ich erhalte "Bus Error" und versuche, stdin in eine Variable char* zu lesen. Ich möchte nur ganze Sachen lesen, die über stdin kommen, und sie zuerst in eine Variable schreiben und dann weiter an der Variablen arbeiten.

Mein Code ist wie folgt:

%Vor%

Aber irgendwie bekomme ich immer "Bus error" durch Aufruf von cat test.txt | myapp , wobei myapp der kompilierte Code ist.

Meine Frage ist, wie lese ich stdin bis EOF in eine Variable? Wie Sie im Code sehen, möchte ich nur die Größe der Eingabe über stdin drucken, in diesem Fall sollte es gleich der Größe der Datei test.txt sein.

Ich dachte, nur mit scanf wäre genug, vielleicht gepufferter Weg, um stdin zu lesen?

    
NovumCoder 23.03.2010, 00:13
quelle

5 Antworten

16

Zuerst übergibst du nicht initialisierte Zeiger, was bedeutet, dass scanf und strcat Speicher schreiben, den du nicht besitzt. Zweitens erwartet strcat zwei nullterminierte Strings, während c nur ein Zeichen ist. Dies wird wiederum dazu führen, dass es Speicher liest, den Sie nicht besitzen. Sie brauchen scanf nicht, weil Sie keine echte Verarbeitung durchführen. Schließlich ist das Lesen eines Buchstabens unnötig langsam. Hier ist der Anfang einer Lösung mit einem resizierbaren Puffer für die letzte Zeichenfolge und einem festen Puffer für den fgets-Aufruf

%Vor%

BEARBEITEN: Wie schon von Wolfer angedeutet, führt ein NULL in Ihrer Eingabe dazu, dass die Zeichenfolge vorzeitig beendet wird, wenn Sie fgets verwenden. getline ist eine bessere Wahl, wenn sie verfügbar ist, da sie die Speicherzuweisung übernimmt und keine Probleme mit NUL hat Eingabe.

    
Matthew Flaschen 23.03.2010, 00:44
quelle
7

Ihr Problem ist, dass Sie niemals c und content zugewiesen haben, also nicht irgendwo definiert sind - sie verweisen wahrscheinlich auf nicht zugeordneten Speicher oder etwas, das gar nicht existiert. Und dann fügst du Daten in sie ein. Sie müssen sie zuerst zuweisen. (Das ist, was ein Busfehler normalerweise bedeutet; Sie haben versucht, einen Speicherzugriff auszuführen, der nicht gültig ist.)

(Da c immer nur ein einzelnes Zeichen enthält, können Sie es als char c deklarieren und &c als scanf übergeben. Es ist nicht erforderlich, eine Zeichenkette zu deklarieren.)

Sobald Sie das getan haben, werden Sie feststellen, dass content lang genug ist, um alle Eingaben zu speichern. Entweder müssen Sie schätzen, wie viele Eingaben Sie erwarten, und es mindestens so lange zuweisen (und dann einen Fehler, wenn Sie das überschreiten), oder Sie benötigen eine Strategie, um sie in einer größeren Größe neu zuzuordnen, wenn sie nicht lang genug ist / p>

Oh, und Sie werden auch auf das Problem stoßen, dass strcat eine Zeichenfolge und kein einzelnes Zeichen erwartet. Selbst wenn Sie c als char* belassen, macht der scanf -Aufruf keine Zeichenfolge. Eine Einzelzeichenfolge ist (im Speicher) ein Zeichen gefolgt von einem Nullzeichen, um das Ende der Zeichenfolge anzuzeigen. scanf , wenn nach einem einzelnen Zeichen gesucht wird, wird nicht das Nullzeichen nach ihm eingefügt. Als Ergebnis wird strcpy nicht wissen, wo das Ende der Zeichenfolge ist, und wird durch den Speicher wandern und nach dem Nullzeichen suchen.

    
Brooks Moses 23.03.2010 00:16
quelle
6

Da dir der eigentliche Inhalt egal ist, warum solltest du eine Saite bauen? Ich würde auch getchar() verwenden:

%Vor%

Dieser Code behandelt Fälle richtig, in denen Ihre Datei '%code%' -Zeichen enthält.

    
Carl Norum 23.03.2010 00:16
quelle
1

Das Problem hier ist, dass Sie eine Zeigervariable referenzieren, die keinen Speicher über malloc zugewiesen hat, daher wären die Ergebnisse nicht definiert und nicht allein, indem strcat für einen undefinierten Zeiger verwendet wird, der auf irgendetwas zeigen könnte Am Ende hast du einen Busfehler!

Dies wäre der festgelegte Code ....

%Vor%

Der Code hebt die Verantwortung des Programmierers hervor, den Speicher zu verwalten - für jedes malloc gibt es ein free , wenn nicht, hast du ein Speicherleck!

Bearbeiten: Danke an David Gelhar für seinen Hinweis auf meinen Fehler! Ich habe den Code oben repariert, um die Korrekturen wiederzugeben ... natürlich könnte der feste Wert von 100 in einer realen Situation vielleicht zu einem #define geändert werden, um es einfach zu machen, den Puffer zu erweitern, indem man über den Menge an Speicher über realloc und trimmen Sie es auf Größe ...

    
t0mm13b 23.03.2010 00:31
quelle
1

Angenommen, Sie möchten Zeichenfolgen (kürzer als MAXL-1 Zeichen) erhalten und Ihre Datei nicht nach Zeichen verarbeiten, habe ich Folgendes getan:

%Vor%     
user3715859 06.06.2014 16:31
quelle

Tags und Links