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?
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
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.
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.
Da dir der eigentliche Inhalt egal ist, warum solltest du eine Saite bauen? Ich würde auch getchar()
verwenden:
Dieser Code behandelt Fälle richtig, in denen Ihre Datei '%code%'
-Zeichen enthält.
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 ...
Angenommen, Sie möchten Zeichenfolgen (kürzer als MAXL-1 Zeichen) erhalten und Ihre Datei nicht nach Zeichen verarbeiten, habe ich Folgendes getan:
%Vor%