C: Dateiinhalt drucken ohne Zwischenspeicherung?

Moin,

  
Angenommen ich möchte über ein C-Programm den Inhalt einer Text-Datei drucken: Ist es nötig, dass ich über fscanf den Inhalt der Datei auslese und in einem String zwischenspeichere, bevor ich die Ausgabe über fprintf an den Drucker schicken kann, oder gibt es auch eine Lösung, bei der ich keine Variable benutzen muss? Also eine Art "direkten Weg". Ich weiß ja schließlich nicht im Vorraus, wie groß die Datei ist und ob der String-Array groß genug ist bzw. wie groß ich ihn anlegen muss ?! Die Zeichen ließen sich natürlich Zählen, aber dazu müsste man sie dann erst mal über printf auf dem Bildschirm ausgeben, nicht wahr?  
  
thx  
moe.  

an sich, ja

Moin,

  
Angenommen ich möchte über ein C-Programm den Inhalt einer  
Text-Datei drucken: Ist es nötig, dass ich über fscanf den  
Inhalt der Datei auslese und in einem String  
zwischenspeichere, bevor ich die Ausgabe über fprintf an den  
Drucker schicken kann, oder gibt es auch eine Lösung, bei der  
ich keine Variable benutzen muss? Also eine Art "direkten  
Weg".

Das direkteste, was ich mir vorstellen kann, ist eine Funktion „openFile()“, die eine
Datei oeffnet, einen char* zurueck gibt, und schliesst sie wieder. Die kannste dann bei fprintf() als Quelle angeben, ohne extra Speicher, also:

 FILE \* fp = 0;
 fp = fopen("schreiben.txt", "at");
 if (!fp) { /\*\*/ }
 fprintf (fp, "%s", openFile("lesen.txt", "rt"));
 fclose(fp);

Wie lange die geoeffnete Datei ist, das wird der dann schon merken. Deine Funktion sollte halt ein ‚\0‘ anhaengen - kriegst Du das hin?

Ich weiß ja schließlich nicht im Vorraus, wie groß die
Datei ist und ob der String-Array groß genug ist bzw. wie groß
ich ihn anlegen muss ?! Die Zeichen ließen sich natürlich
Zählen, aber dazu müsste man sie dann erst mal über printf auf
dem Bildschirm ausgeben, nicht wahr?

Muss man gar nicht. Du kannst die eizelnen Zeichen mit fgetc() abrattern lassen, die Ausgabe am Bildschirm wuerde das ganze nur einbremsen:

// geoeffnet ist sie....
long i;
char ch = 32;
for (i=0; ch != EOF; i++)
 {
 ch = fgetc(fp);
 }
long groessenMerker = i;

dann musste halt das Datei-Caret mit fseek() wieder an den Anfang setzen, oder schliessen und neu oeffnen.
Gucke doch mal hier rein, da findest Du schlicht alles zum Thema „FILE *“:
http://www.cplusplus.com/ref/cstdio/fgetc.html

Aber Du kannst die Groesse (auf windows API) auch billiger kriegen:

ULONG getFileSize(const char \*path)
 {
 WIN32\_FIND\_DATAA wfd;
 wfd.nFileSizeLow = 0;
 HANDLE hFind = INVALID\_HANDLE\_VALUE;

 hFind = FindFirstFile(path, &wfd);
 if (hFind == INVALID\_HANDLE\_VALUE) { return 0; }

 return wfd.nFileSizeLow;
 }

thx
moe.

plz
lg
Martin

Uuuuups, zum drucken braucht es natuerlich „stdprn“ anstelle des FILE *, sorry.

lg
Martin

Hallo,

  1. was du zwischenspeicherst, ist ja weitgehend in dein Belieben gestellt - die ganze Datei ist da eher eine der schlechteren Ideen, gebräuchlich wäre 1 Zeichen, eine Zeile oder z.B. 256 Zeichen. 1 Zeichen ist schlecht wegen der Performance, aber man braucht sich um nichts anderes zu kümmern als um das Ende der Datei. Zeilen setzt voraus, dass die Datei auch in Zeilen eingeteilt ist und man die maximale Länge weiss. Zwischenspeichern von x Bytes ist am effektivsten, bei x > 1000 sehr performant und auch das, was das (jedes) Betriebssystem macht. Man hat bloss das Problem, dass am Schluss der Buffer nicht mehr ganz gefüllt wird und dann muss man eben weniger als x Zeichen weitergeben.

  2. es ist problemlos möglich, die Grösse der Datei zu bestimmen, dafür gibt es Standardfunktionen oder man macht einfach ein seek ans Dateiende - Die Position ist dann die Dateigrösse. Die Datei ganz einzulesen ist aber zumindest nicht gute Programmierpraxis, u.a. gibt es IMMER eine Datei, die dafür zu gross ist. Windows speichert die eingelesene Datei zwar auf der Platte zwischen, während du sie im virtuellen Memory vermutest, aber bei 4 GByte werden eben 4 GByte zusätzlich und unnötig gebraucht.

Gruss Reinhard

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Danke.
.