Zeichen an Zeilenende anfügen



  • Hi,

    Ich möchte ein Programm schreiben, dass eine Datei öffnet und an jede Zeile bestimme Zeichen anhängt. Hier mein Code der leider nicht funktioniert:

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        FILE *pf;
        char chr;
        char word[3] = "ab";
    
        pf = fopen("file.txt", "r+");
    
        if(!pf)
               {
               printf("Fehler beim Oeffnen der Datei!");
               exit(1);
               }
    
        while(1)
            {
            chr = fgetc(pf);
    
            if(chr == '\n')
                   {
                   fprintf(pf, "%s", word);
                   }
    
            if(feof(pf))
                break;
            }
    
        fclose(pf);
    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    


  • Hi,
    anhängen geht so nicht. So überschreibst du Zeichen, hängst aber keine an.
    Mach das so:
    Kopiere zeichenweise von "file.txt" nach "temp.txt", wenn ein '\n' auftaucht, schreib die hinzuzufügenden Zeichen deiner Wahl. Danach kannst du "file.txt" löschen und "temp.txt" in "file.txt" umbenennen, oder was auch immer.



  • Pappa schrieb:

    Hi,
    anhängen geht so nicht. So überschreibst du Zeichen, hängst aber keine an.
    Mach das so:
    Kopiere zeichenweise von "file.txt" nach "temp.txt", wenn ein '\n' auftaucht, schreib die hinzuzufügenden Zeichen deiner Wahl. Danach kannst du "file.txt" löschen und "temp.txt" in "file.txt" umbenennen, oder was auch immer.

    Ok habs jetzt geändert.
    Komischerweise das 'ÿ' Zeichen an´s Ende der Datei angefügt.

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        FILE *pf;
        FILE *pf2;
        char chr;
        char word[100];
    
        printf("Welche Zeichen willst Du anhaengen? ");
        scanf("%s", word);
    
        pf = fopen("file.txt", "r");
        pf2 = fopen("temp.txt", "w");
    
        if(!pf)
               {
               printf("Fehler beim Oeffnen der Datei!");
               exit(1);
               }
    
        while(1)
            {
            chr = fgetc(pf);
            fprintf(pf2, "%c", chr);
    
            if(chr == '\n')
                   {
                   fseek(pf2, -2, SEEK_CUR);
                   fprintf(pf2, "%s\n", word);
                   }
    
            if(feof(pf))
                break;
            }
    
        fclose(pf);
        fclose(pf2);
    
        remove("file.txt");
        rename("temp.txt", "file.txt");
    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    MfG



  • Vermutlich weil du das EOF in die Datei schreibst. Du solltest die eingelesenen Zeichen auf EOF prüfen. Ein fseek brauchst du auch nicht unbedingt, wenn du die Schleife clever baust:

    int eret()
    {
    	fprintf( stderr, "%s\n", strerror(errno));
    	fcloseall();
    	return 1;
    }
    
    int main()
    {
    	FILE* in = NULL, *out = NULL;
    	char* fname_in = "test.txt", *fname_out = "temp.txt";
    	int c = 0; // Wichtig: Datentyp Integer wegen korrekter EOF Erkennung!
    
    	in = fopen ( fname_in, "r" );
    	out = fopen ( fname_out, "w" );
    
    	if ( in == NULL || out == NULL )
    		return eret();
    
    	while ( (c = fgetc(in)) != EOF )
    	{
    		if ( c == '\n' )
    			fputs( " --- Additional characters.", out );
    		fputc(c,out);
    	}
    
    	fclose(in);
    	fclose(out);
    
    	return 0;
    }
    


  • Spitze! 😃
    Nur versteh ich nicht wie EOF erkannt wird, aber dazu gibts bestimmt gute Beschreibungen.



  • EOF ist ein Makro, das in der stdio.h z.B. so definiert ist:

    #define EOF -1
    

    und je nach System verschiedene Werte haben kann.



  • Pappa schrieb:

    EOF ist ein Makro, das in der stdio.h z.B. so definiert ist:

    #define EOF -1
    

    und je nach System verschiedene Werte haben kann.

    Ok. Aber wie kann fgetc etwas auslesen wo gar nichts ist.
    Auch bei \n.



  • Das passiert intern, da braucht sich der Programmierer nicht drum
    zu kümmern.

    int c = 0;
    FILE* in;
    ...
    while ( c != EOF )
    {
    c = fgetc(in);
    ...

    Solange es etwas einzulesen gibt, steht in der Variable c ein von EOF verschiedener
    Wert drin. Dieser Wert steht auch in der Datei drin ( der Wert, auf den der Dateizeiger gerade zeigt).
    Zeigt der Dateizeiger hinter das Letzte Zeichen der Datei, wird beim Versuch einen Wert
    einzulesen der EOF Wert in die Variable c reingeschrieben. Der Wert EOF steht also nicht in der Datei drin, der Wert wird vom System, bzw. von der Funktion fgetc geliefert.



  • Pappa schrieb:

    Das passiert intern, da braucht sich der Programmierer nicht drum
    zu kümmern.

    int c = 0;
    FILE* in;
    ...
    while ( c != EOF )
    {
    c = fgetc(in);
    ...

    Solange es etwas einzulesen gibt, steht in der Variable c ein von EOF verschiedener
    Wert drin. Dieser Wert steht auch in der Datei drin ( der Wert, auf den der Dateizeiger gerade zeigt).
    Zeigt der Dateizeiger hinter das Letzte Zeichen der Datei, wird beim Versuch einen Wert
    einzulesen der EOF Wert in die Variable c reingeschrieben. Der Wert EOF steht also nicht in der Datei drin, der Wert wird vom System, bzw. von der Funktion fgetc geliefert.

    OK verstehe. Thx.
    Ich hab mal eine .txt im Hexeditor geöffnet und gesehen, '\n' für 0x0D0A steht?
    Wie wird jetzt eine Datei in C++ geöffnet? Alles hexadezimal ausgelesen?

    MfG 🙂



  • Sohn schrieb:

    Ich hab mal eine .txt im Hexeditor geöffnet und gesehen, '\n' für 0x0D0A steht?

    Nicht ganz. 0x0D0A besteht aus zwei Byte, wobei das Byte mit dem Wert 0x0A dem Zeilenumbruch '\n' und 0x0D dem Wagenrücklauf '\r' entspricht.
    Das ganze zusammen ergibt das Carriage Return/Line Feed Paar "\r\n" und ist
    typisch für Windows Textdateien. Unter Windows wird das Lesen/Schreiben im Textmodus
    und im Binärmodus unterschieden. Im Textmodus bekommst du das '\r' beim Lesen nicht zu sehen, im Binärmodus ja:

    #include <stdio.h> 
    
    int eret() 
    { 
        fprintf( stderr, "%s\n", strerror(errno)); 
        fcloseall(); 
        return 1; 
    } 
    
    int main()
    {
    	FILE* in;
    	char* fname = "test.txt";
    	char c = 0;
    
    	if ( NULL == (in = fopen ( fname, "r" ))) // Textmodus.
    		return eret();
    
    	while (EOF != ( c = fgetc(in)))
    		if ( c == '\r' )
    			puts( "Text mode, found carriage return!" );
    
    	fclose(in);
    
    	if ( NULL == (in = fopen ( fname, "rb" ))) // Binärmodus.
    		return eret();
    
    	while (EOF != ( c = fgetc(in)))
    		if ( c == '\r' )
    			puts( "Binary mode, found carriage return!" );
    
    	fclose(in);
    
    	return 0;   
    }
    

    Beim Schreiben im Textmodus unter Windows wird das '\n' durch ein "\r\n" ersetzt. ⚠

    Sohn schrieb:

    Wie wird jetzt eine Datei in C++ geöffnet?

    In C++ funktioniert Lesen/Schreiben so: http://www.c-plusplus.net/forum/viewtopic-var-t-is-251703.html
    Da lassen sich mit den Flags ios::binary, ios::text die entsprechenden Modi setzen.

    Sohn schrieb:

    Alles hexadezimal ausgelesen?

    Der Dateiinhalt steht zunächst binär, als eine Folge von Einsen und
    Nullen im Speicher. Das lässt sich oktal, dezimal, hexadezimal etc. interpretieren.


Anmelden zum Antworten