fopen/fprintf - merkwürdiges Ergebnis



  • Hallo zusammen,

    ich versuche gerade eines meiner PHP-Skripte in C/C++ zu übertragen. Dabei soll eine Datei geladen, bearbeitet und unter neuem Namen gespeichert werden. Der "Lernerfolg" (bin C/C++ Neuling) steht dabei an erster Stelle; Aber, nun ja. Ich kann mir folgenden "Fehler" nicht erklären...

    Bisher läd mein Programm eine Datei ein und speichert sie direkt wieder ab. Eigentlich sollte die Eingangs- und Ausgangsdatei also identisch sein.

    Allerdings werden der Ausgangsdatei noch verschiedenste Sonderzeichen angehängt, die je nach Dateiende der Ursprungsdatei (auch in der Länge) variieren.

    Ich hab also erstmal einen Kollegen um Rat gefragt, der sich mit der Sprache schon ein wenig länger beschäftigt und war dann leicht verwundert, dass bei ihm keinerlei Sonderzeichen erscheinen.

    Auch Tests auf anderen PCs, die mir hier zur Verfügung stehen war keinerlei Fehler zu sehen.

    Weiss nicht inwieweit das eine Rolle spielt, aber der "Problem-PC" ist ein P4 mit HT und onboard-Grafikkarte mit Win XP.

    Was ich bisher als "Fehlerquellen" getestet hab:
    - HT
    - onBoard Grafik

    Meine Frage... was könnte da schief laufen? Da es ja nur an diesem einem PC nicht zu klappen scheint, scheint es ja kein Code-Problem zu sein.

    #include <stdio.h>
    #include <stdlib.h>
    
    int main () {
      FILE * Datei;
      int iSize;
      char * buffer;
    
      Datei = fopen ( "text.txt" , "rb" );
      if (Datei==NULL) exit (1);
    
      // obtain file size.
      fseek (Datei , 0 , SEEK_END);
      iSize = ftell (Datei);
      rewind (Datei);
    
      // allocate memory to contain the whole file.
      buffer = (char*) malloc (iSize);
      if (buffer == NULL) exit (2);
    
      // copy the file into the buffer.
      fread (buffer,1,iSize,Datei);
    
      // terminate
      fclose (Datei);
    
      Datei = fopen ("test_out.txt","w+");
      fprintf (Datei, "%s", buffer);
      fclose (Datei);
    
      free (buffer);
      return 0;
    }
    

    text.txt:

    Hallo, Welt.
    

    test_out.txt

    Hallo, Welt.rect
    

    Danke im Voraus,



  • hmm..
    wenn du mit "fread" aus der datei ausliest..
    warum schreibtst du dann nicht mit "fwrite" in die 2.datei?

    ich hätte da noch eine frage: für was steht eigendlich "w+"?



  • chille07 schrieb:

    ich hätte da noch eine frage: für was steht eigendlich "w+"?

    Bei "w+" wird eine leere Datei zum lesen/schreiben geöffnet. Wenn die Datei mit dem Namen bereits existiert wird der Inhalt vor dem öffnen gelöscht.

    chille07 schrieb:

    hmm..
    wenn du mit "fread" aus der datei ausliest..
    warum schreibtst du dann nicht mit "fwrite" in die 2.datei?

    fprintf() hab ich benutzt, weil es von einem Beispiel einer Webseite stammt, wo der Autor eben diese Funktion benutzt hat. Ich habe jetzt mal fwrite() probiert. Leider mit den selben Problem wie oben beschrieben 😞



  • Mach mal statt rewind() wieder ein fseek() mit SEEK_BEG. Das rewind() kenn ich nicht und nichtmal SEEK_END/TELL/SEEK_BEG funktioniert immer.

    MfG SideWinder



  • SideWinder schrieb:

    Mach mal statt rewind() wieder ein fseek() mit SEEK_BEG. Das rewind() kenn ich nicht und nichtmal SEEK_END/TELL/SEEK_BEG funktioniert immer.

    Hab' ich jetzt. Problem bleibt bestehen 😕



  • Oh, ich hab gemerkt, dass ich veregssen hatte die .exe zu löschen und der Compiler die Datei nicht überschrieben hatte. Die Ausgabe in eine Datei funktioniert nun, auch wenn ich nicht weiss ob es an fwrite() oder der fseek() Änderung liegt.

    Ach ja.. @SideWinder: Es war übrigens SEEK_SET nicht SEEK_BEG 🙂

    Nun ja.. mein Problem ist damit fast gelöst. Allerdings bleiben die "merkwürdigen Sondercode-Anhängel" bestehen wenn ich mit:

    printf("%s",buffer);
    

    den erhaltenen Dateiinhalt in der Konsole ausgeben will. Und zwar wieder nur auf diesem einem System 😞



  • Was isn das für ein System? Speichert das eventuell am Ende der Datei noch irgendwelche Informationen ab?

    Mach zudem mal aus fprintf() ein fputs() wenn du schon so nen tollen Puffer hast. Eventuell formatiert der noch was dran?!

    MfG SideWinder



  • 1. Wenn man binär liest, sollte man am besten auch wieder binär schreiben.
    2. fread() liest die Anzahl der angegebenen Zeichen ein und nicht mehr. Es hängt also kein '\0' an das Ende!! Dahingehend ist klar, dass fputs() & Co seltsame Zeichen hinten dranhängen.
    3. Der Fehler wurde übrigens durch das fwrite() bereinigt, da dies ja auch nur die bestimmte Anzahl an Zeichen schreibt und nicht bis zum Stringendezeichen '\0' das macht, wie es eben fprintf() usw. macht.



  • Standard-Feilferarbeitung ist imho sowieso unbrauchbar, viel zu viele Möglichkeiten nichts zu tun. Ich benütze eigentlich immer die System-Variante, Konsolenprogramme laufen sowieso nur unter Windows 🙂

    MfG SideWinder



  • SideWinder schrieb:

    Was isn das für ein System? Speichert das eventuell am Ende der Datei noch irgendwelche Informationen ab?

    Mit "System" war in dem Fall mein Rechner, der Probleme macht, gemeint.
    Das ist ein P4 Northwood 3Ghz, 1024 TwinMOS RAM, Board mit Intel i865G Chipsatz.

    Bei den anderen Rechnern weiss ich das nicht so genau. Der Rechner von meinem Bekannten ist ebenfalls ein Northwood, der Rechner von meinem Bruder ist glaube ich ein P4 Willamette und der meiner Mutter ein neuerer Celeron.

    Was mich bei der ganzen Sache ja wundert ist, dass allein mein Rechner die Sonderzeichen anzeigt/anfügt(?)

    SideWinder schrieb:

    Mach zudem mal aus fprintf() ein fputs() wenn du schon so nen tollen Puffer hast. Eventuell formatiert der noch was dran?!

    Hab' es mit fputs(buffer,stdout); versucht. Keine Änderung, selber Fehler.

    AJ schrieb:

    1. Wenn man binär liest, sollte man am besten auch wieder binär schreiben.

    Entschuldige. Ich bin ursprünglich PHP Programmierer und da spielt es meist keine Rolle wie man eine Datei einließt. Da es sich bei meiner Datei nur um Text-Daten handelt hab ich es auf text-mode geändert. Danke für den Hinweis 🙂

    Hier also der aktuelle Code...

    #include <stdio.h>
    #include <stdlib.h>
    
    int main () {
      FILE * Datei;
      long lSize;
      char * buffer;
    
      Datei = fopen ("test.txt","rt");
      if (Datei==NULL) exit (1);
    
      // obtain file size.
      fseek (Datei , 0 , SEEK_END);
      lSize = ftell (Datei);
      fseek (Datei , 0 , SEEK_SET); 
    
      // allocate memory to contain the whole file.
      buffer = (char*) malloc (lSize);
      if (buffer == NULL) exit (2);
    
      // copy the file into the buffer.
      fread (buffer,1,lSize,Datei);
    
      // terminate
      fclose (Datei);
    
      // output 
      fputs(buffer,stdout);
    
      Datei = fopen ("text_out.txt","wt");
      fwrite (buffer, 1, lSize, Datei);
      fclose (Datei);
    
      free (buffer);
      return 0;
    }
    

    Und hier noch ein Screenshot der Ausgabefenster mit verschiedenem Dateiende der Quelldatei (test.txt). Damit ihr euch vorstellen könnt, wovon ich rede...

    Fehler (PNG, 8kB)



  • Selbstzitate sind doch was schönes :p .

    AJ schrieb:

    2. fread() liest die Anzahl der angegebenen Zeichen ein und nicht mehr. Es hängt also kein '\0' an das Ende!! Dahingehend ist klar, dass fputs() & Co seltsame Zeichen hinten dranhängen.

    Du hast also zwei Möglichkeiten:

    Entweder
    1. Du schreibst mit fwrite() o. ä. nur eine bestimmte Anzahl an Zeichen
    oder
    2. Du allokierst ein Byte mehr Speicher und hängst nach dem fread() ans Ende deines Buffers eine '\0' an, damit fputs(), fprintf(), usw. auch erkennen können, dass dein String zuende ist.



  • 🙄 Ehem... sorry...

    Wußte nicht, dass das schon die Lösung des Problems war. *hust hust*
    Bin von PHP gewohnt, dass einfach ausgegeben wird, was in einer Variable steckt und das wars. Variablentypen und dergleichen sind absolutes Neuland... bin verwöhnt. 😞

    Hab eben noch einen anderen Bekannten um Hilfe gebeten und seine Lösung entspricht deinem zweiten Lösungsweg... 🙂

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    	FILE * Datei;
    	long lSize;
    	char * buffer;
    
    	Datei = fopen ("test.txt","rt");
    	if (Datei==NULL)
    		exit(1);
    
    	// obtain file size.
    	fseek (Datei , 0 , SEEK_END);
    	lSize = ftell (Datei);
    	fseek (Datei , 0 , SEEK_SET); 
    
    	// allocate memory to contain the whole file.
    	buffer = (char*) malloc (lSize+1);
    	if (buffer == NULL)
    		exit(2);
    
    	// copy the file into the buffer.
    	size_t ReadSize;
    	ReadSize=fread(buffer,1,lSize,Datei);
    
    	// terminate
    	fclose (Datei);
    
    	buffer[ReadSize]='\0';
    	printf("%s\n",buffer);
    
    	Datei = fopen ("text_out.txt","wt");
    	fwrite (buffer, 1, ReadSize, Datei);	
    	fclose (Datei);
    
    	free (buffer);
    	return 0;
    }
    

    Nochmal danke an alle.

    Und ja...
    Ich seh's ein gibt noch ne Menge zu lernen 😉


Anmelden zum Antworten