[gelöst] Wie kann ich ein FILE als Parameter einer Funktion übergeben?
-
Hallo,
ich möchte gern im Hauptprogramm eine Datei öffnen und dann in einer Funktion etwas in die Datei schreiben. (Die Funktion will ich später öfter aufrufen; deswegen möchte ich eben nicht den Dateinamen übergeben und jedes Mal in der Funktion die Datei öffnen und wieder schließen.)
Ich stelle mir das mehr oder weniger so vor:
#include <stdio.h> void speichern(FILE datei) { fputc('A', &datei); } int main() { FILE *datei = new FILE; datei = fopen ("test.txt","w"); speichern(*datei); fclose(datei); }Dieser Code wird auch kompiliert, aber wenn ich das Programm starte, passiert ein
Segmentation fault. Ich vermute mal, weilfputcnicht in diedateischreibt, sondern versucht an die Adresse des Zeigers aufdateizu schreiben.Kann mir jemand sagen, was ich korrigieren muss?
Vielen Dank im Voraus!
-
Wieso übergibst du nicht einfach den Zeiger den du ja schon in der main Funktion hast?
-
tda schrieb:
Hallo,
ich möchte gern im Hauptprogramm eine Datei öffnen und dann in einer Funktion etwas in die Datei schreiben. (Die Funktion will ich später öfter aufrufen; deswegen möchte ich eben nicht den Dateinamen übergeben und jedes Mal in der Funktion die Datei öffnen und wieder schließen.)
Ich stelle mir das mehr oder weniger so vor:
#include <stdio.h> void speichern(FILE datei) { fputc('A', &datei); } int main() { FILE *datei = new FILE; datei = fopen ("test.txt","w"); speichern(*datei); fclose(datei); }Dieser Code wird auch kompiliert, aber wenn ich das Programm starte, passiert ein
Segmentation fault. Ich vermute mal, weilfputcnicht in diedateischreibt, sondern versucht an die Adresse des Zeigers aufdateizu schreiben.Kann mir jemand sagen, was ich korrigieren muss?
Vielen Dank im Voraus!
#include <stdio.h> void speichern(FILE* datei) { fputc('A', datei); } int main() { FILE *datei = new FILE; datei = fopen ("test.txt","w"); speichern(datei); fclose(datei); }
-
@Zeigerübergabe: An sowas hatte ich auch gedacht, wusste dann aber nicht so recht, wie ich in der Funktion damit umgehen muss.
@FileZeiger: Ja, das ist genau, was ich wollte. (Wann etwas Zeiger oder Referenz oder was auch immer ist, ist bei mir noch größtenteils geschicktes Raten und Rumprobieren.
)Vielen Dank für die schnelle Hilfe!
-
FILE *datei = new FILE; datei = fopen ("test.txt","w");Hier hast du ein schönes Memory Leak. Schreib lieber
FILE* datei = fopen("test.txt", "w");Wenn du tatsächlich C++ programmierst (was wegen
newanzunehmen ist), kannst du dir sonst auch mal die IO-Streams (std::fstream) anschauen. Die schliessen sich zum Beispiel auch selbst.
-
Nexus schrieb:
Schreib lieber
FILE* datei = fopen("test.txt", "w");Das habe ich inzwischen gemacht. Das mit dem
newwar nur beim Rumprobieren entstanden...Nexus schrieb:
kannst du dir sonst auch mal die IO-Streams (
std::fstream) anschauen. Die schliessen sich zum Beispiel auch selbst.Haben die sonst noch irgendwelche Vorteile?
Ich war auch schon auf die gestoßen, ürsprünglich aber zunächst nur auf
ostream::writeundistream::read, was mir unnötig kompliziert schien. Da ich meine Daten binär und daher durchaus byte-weise schreiben und lesen kann, schien mirfputcangemessener. Aberostream::putundistream::getdürften ja etwa das gleiche tun wiefputcundfgetc, oder?
-
Vorteil von std::fstream ist, dass einem mehr Sicherheit durch Exceptions gewährleistet wird. Für byteweises (, binäres) einlesen gibt es std::stringstream(>>).
-
Exceptionsicherheit: Ja. Stringstreams für binäres Einlesen: Nein.
stringstreambietet (bis auf das fehlendeopen()undclose()) genau die gleichen Operationen wiefstream, denn beide sind voniostreamabgeleitet. Siehe http://www.cplusplus.com/reference/iostream/. Ihre wahren Stärken könnnen die iostreams zwar nur beim formatierter Ein-/Ausgabe mit den << und >> Operatoren ausspielen, dennoch sind sie den Sachen aus<cstdio>(<stdio.h>ist veraltet!) vorzuziehen. Übrigens: Wenn du byteweise (==> binär) schreibst solltest du statt "w" "wb", bzw. bei fstreamios::binarybenutzen.
-
Danke für die Antworten!
Oberon_0 schrieb:
Übrigens: Wenn du byteweise (==> binär) schreibst solltest du statt "w" "wb", bzw. bei fstream
ios::binarybenutzen.Das ist mir auch schonmal über den Weg gelaufen. Was macht das eigentlich für einen Unterschied?
Oberon_0 schrieb:
Ihre wahren Stärken könnnen die iostreams zwar nur beim formatierter Ein-/Ausgabe mit den << und >> Operatoren ausspielen, dennoch sind sie den Sachen aus
<cstdio>(<stdio.h>ist veraltet!) vorzuziehen.OK. Ich habe inzwischen mein Projekt komplett auf
fstreamumgestellt. Falls das noch jemand anderes interessiert, hier nochmal die Kurzfassung (mit einer zusätzlichen Zwischen-Funktion):#include <iostream> #include <fstream> using namespace std; void speichern(ofstream &datei) { datei.put('B'); } void mehrere_speichern(ofstream &datei) { speichern(datei); speichern(datei); } int main() { ofstream datei("test.txt", ios::out | ios::binary); speichern(datei); mehrere_speichern(datei); }
-
Die Parameter w und wb sind ja zunächst nur Abkürzüngen, welche angeben, mit welchen "Anforderungen" eine Datei geöffnet werden soll.
Dabei steht das w für Schreibzugriff (write) und das b für binären Zugriff (binary).
In Kombination heißt wb dann natürlich: Binär schreiben.
Binär liest und schreibt man immer dann, wenn man eine Datei exakt kopieren will. Andernfalls würden Terminierungszeichen und andere Steuerzeichen Probleme machen und die Datei unbrauchbar machen.
Oder man schreibt binär, wenn man eigene Strukturen speichern möchte. Auch hier wären Steuerzeichen hinderlich und es muss entsprechedn binär geschrieben werden
Aber das Thema wird umso komplizierter, umso mehr man an Plattformunabhängigkeit interessiert ist.Will man reinen Text speichern, so ist ein binärer Zugriff in der Regel nicht notwendig und bereitet nur Probleme. Einfach mal experimentieren

-
Für meinen Fall brauche ich auf jeden Fall binäre Dateien. Meine Frage war nur, was es für einen Unterschied macht, ob ich eine Datei mit "
w" oder "wb" (bzw. mit oder ohneios::binary) öffne, aber inzwischen habe ich eine Antwort gefunden: inhaltlich offenbar keinen, aber benutzen sollte ich "wb" bzw.ios::binarydennoch.<a href= schrieb:
cplusplus.com">In many environments, such as most UNIX-based systems, it makes no difference to open a file as a text file or a binary file; Both are treated exactly the same way, but differentiation is recommended for a better portability.
Vielen Dank für all die Hilfe!

-
noch als kleiner nachtrag: unter windows gibts sehr wohl nen unterschied - hab hier schon mehrfach gehört, dass jmd nen \r\n beim "normalen" auslesen bekommen hat, obwohl eigtl nur ein \n in der datei stand - beim binären lesen hatte das dann auch geklappt ^^
also wenn du binär willst, nimm binär - verlass dich nicht drauf, dass es keinen unterschied macht.bb