Datei schreiben



  • Ähm O_o

    "ned" = "nicht" heißt

    scanf("%s", &name);
    

    ist böse und

    scanf("%s", name);
    

    ist schon um ein ganzes Stück besser.



  • @feigling: also ich kenne das so, dass man bei scanf den adressoperator braucht! schließlich soll die variable ja einen wert bekommen!

    bei printf wird der adressoperator weggelassen! oder irre ich mich da jetzt! 😮
    bin mir aber ziemlich sicher!



  • Also ich habe jetzt mehreres probiert:

    1. Versuch:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 30
    
    int main (void)
    {
    	FILE *profil;
    	char name[MAX]; 
    	char vorname[MAX]; 
    	char strasse[MAX]; 
    	char ort[MAX]; 
    	char filename[MAX];
    
    	printf("Geben Sie den Namen der Datei ein: ");
    	scanf("%s",&filename);
    
    	if((profil=fopen(filename,"w"))==NULL)
    	{
    		printf("Fehler beim Erstellen oder Oeffnen der Datei\n");
    		exit(1);
    	}
    
    	printf("Name: ");
    	fgets(name,MAX,stdin);
    
    	printf("Vorname: ");
    	fgets(vorname,MAX,stdin);
    
    	printf("Strasse: ");
    	fgets(strasse,MAX,stdin);
    
    	printf("Ort: ");
    	fgets(ort,MAX,stdin);
    
    	fprintf(profil,"Name: %s\nVorname: %s\nStrasse: %s\nOrt: %s", name, vorname, strasse, ort);
    
    	fclose(profil);
    
    	return 0;
    }
    

    2. Versuch:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 30
    
    int main (void)
    {
    	FILE *profil;
    	char name[MAX]; 
    	char vorname[MAX]; 
    	char strasse[MAX]; 
    	char ort[MAX]; 
    	char filename[MAX];
    
    	printf("Geben Sie den Namen der Datei ein: ");
    	scanf("%s",&filename);
    
    	if((profil=fopen(filename,"w"))==NULL)
    	{
    		printf("Fehler beim Erstellen oder Oeffnen der Datei\n");
    		exit(1);
    	}
    
    	printf("Name: ");
    	fgets(name,sizeof(name),stdin);
    
    	printf("Vorname: ");
    	fgets(vorname,sizeof(vorname),stdin);
    
    	printf("Strasse: ");
    	fgets(strasse,sizeof(strasse),stdin);
    
    	printf("Ort: ");
    	fgets(ort,sizeof(ort),stdin);
    
    	fprintf(profil,"Name: %s\nVorname: %s\nStrasse: %s\nOrt: %s", name, vorname, strasse, ort);
    
    	fclose(profil);
    
    	return 0;
    }
    

    Jetzt habe ich zwei Probleme:
    1. Bei beiden Versionen, die sich vom Programmablauf ja nicht unterscheiden, kommt dieser fehler:
    FEHLER

    Nachdem ich den Namen bzw. Pfad der Datei angegeben habe unter Enter drücke, bringt er sofort "Name: Vorname:"! Ich glaube, es hängt mit dem scanf vorher zusammen! Ich habe das auch schon in "fgets(filename,MAX,stdin);" geändert, aber dann öffnet er die Datei nicht!

    2.(eigentlich nicht so wichtig) Beim Schreiben macht er nach jeder Zeile eine Freizeile bzw. Absatz!



  • Nachdem ich den Namen bzw. Pfad der Datei angegeben habe unter Enter drücke, bringt er sofort "Name: Vorname:"!

    das kommt, weil du vergessen hast den eingabepuffer zu leeren.

    Ich habe das auch schon in "fgets(filename,MAX,stdin);" geändert, aber dann öffnet er die Datei nicht!

    2.(eigentlich nicht so wichtig) Beim Schreiben macht er nach jeder Zeile eine Freizeile bzw. Absatz!

    du hast vergessen, das '\n' am ende des strings zu entfernen, das fgets noch mitnimmt.

    printf("Geben Sie den Namen der Datei ein: ");
        scanf("%s",&filename);
    

    scanf erwartet beim einlesen immer die adresse. bei 'normalen' variablen brauchst du dafür den adressoperator '&'. wenn du ein array oder zeiger auf einen speicherblock hast, ist der name schon die adresse, da wird also '&' weggelassen.



  • sheddy schrieb:

    @feigling: also ich kenne das so, dass man bei scanf den adressoperator braucht! schließlich soll die variable ja einen wert bekommen!

    aber nicht immer 😮 mann muss eine Adresse übergeben, wo man die Daten geschrieben haben will, aber wenn die Variable von alleine auf die gewünschte Adresse deferenziert, braucht man kein & Operator.

    int i;
    /* &i, weil scanf den Inhalt der Adresse
       i verändern soll, d.h. man übergibt,
       die Adresse, wo geschrieben werden soll */
    scanf("%d", &i);
    
    char filename[MAX];
    /* nur filename, weil (char *) filename == &filename[0], d.h.
       filename "zeigt" [1] auf die Adresse, wo das Feld angelegt ist */
    scanf("%s", filename);
    

    Wenn du scanf("%s", &filename) hast, dann wird scanf den Inhalt von filename ändern, d.h. danach wird filename nicht auf das Feld "zeigen".

    [1] "zeigt" in Anführungszeichen, weil ein Array kein Zeiger ist, jedoch dort wie einer funktioniert.



  • ja, okay, ich verstehe!! aber wie lösche bzw. gebe den puffer wieder frei?



  • Welchen Puffer? Die Arrays für die Eingabedaten werden automatisch am Programmende freigegeben, du mußt nur die Datei per fclose() weider schließen, wenn du sie nicht mehr brauchst.

    (obwohl, bei Programmende werden offene Dateien auch automatisch geschlossen)



  • ich meine den puffer von fgets!

    Ich schrieb:

    1. Bei beiden Versionen, die sich vom Programmablauf ja nicht unterscheiden, kommt dieser fehler:
    FEHLER

    Nachdem ich den Namen bzw. Pfad der Datei angegeben habe unter Enter drücke, bringt er sofort "Name: Vorname:"! Ich glaube, es hängt mit dem scanf vorher zusammen! Ich habe das auch schon in "fgets(filename,MAX,stdin);" geändert, aber dann öffnet er die Datei nicht!

    Und Jay antwortete darauf:

    Nachdem ich den Namen bzw. Pfad der Datei angegeben habe unter Enter drücke, bringt er sofort "Name: Vorname:"!

    das kommt, weil du vergessen hast den eingabepuffer zu leeren.

    Ich habe mich ja mit fgets befasst, aber ich finde keine angabe zum leeren des fgets-puffer!



  • Achso, das meinst du. Der Punkt ist ganz einfach, daß nach der Eingabe des Dateinamens noch das abschließende \n im Tastaturpuffer wartet und beim nächsten Lesezugriff auf stdin geliefert wird. Die Lösung dieses Problems sieht so aus:

    while(fgetc(stdin)!='\n);
    

    (Alternativen findest du in der Konsolen-FAQ unter "Automatisches Schließen verhindern")



  • Also ich habe das ganze Problem jetzt so gelöst! Eigentlich wollte ich nur den Absatz weiter am Ende des Programms lösen, aber damit ging das ganze Programm das Reibungslos! Es seiht jetzt so aus:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 40
    
    /* Absatz ('\n') entfernen */
    void Ende(char *str)
    {
    	size_t laenge;
    	laenge = strlen(str);
    	str[laenge-1]='\0';
    
    }
    
    int main (void)
    {
    	FILE *profil;
    	char name[MAX]; 
    	char vorname[MAX]; 
    	char strasse[MAX]; 
    	char ort[MAX]; 
    	char filename[MAX];
    
    	printf("Geben Sie den Namen der Datei ein: ");
    	fgets(filename,MAX,stdin);
    	Ende(filename);
    	/*scanf("%s",filename);*/ /* ohne '&', weil filename ein char-array ist */
    	/* Fehler mit "Name: Vorname: */
    
    	if((profil=fopen(filename,"w"))==NULL)
    	{
    		printf("Fehler beim Erstellen oder Oeffnen der Datei\n");
    		exit(1);
    	}
    
    	printf("Name: ");
    	fgets(name,MAX,stdin);
    	Ende(name);
    
    	printf("Vorname: ");
    	fgets(vorname,MAX,stdin);
    	Ende(vorname);
    
    	printf("Strasse: ");
    	fgets(strasse,MAX,stdin);
    	Ende(strasse);
    
    	printf("Ort: ");
    	fgets(ort,MAX,stdin);
    	Ende(ort);
    
    	fprintf(profil,"Name: %s\nVorname: %s\nStrasse: %s\nOrt: %s", name, vorname, strasse, ort);
    
    	printf("\nDatei erfolgreich erstellt\n");
    
    	fclose(profil);
    
    	return 0;
    }
    

    1. Die Eingabe für den Pfad funktionierte anfangs nicht mit fgets! Kaum das dadurch, dass fgets am Ende immer ein "\n" mit dran hängt??

    2. Was mich immernoch interesiert:
    Ich könnte die Eingabe der Datei bzw. des Pfades ja auch per scanf lösen! Aber dann taucht wieder dieses Problem auf! Kann mir das noch jemand erklären, wie ich das beseitige?

    vielen Dank an alle!
    gruß sdy



  • 1. ja, fgets schreibt das \n Zeichen.
    2. das kann passieren, dass stdin nach dem ersten scanf nicht "leer" bleibt, beim zweiten scanf passt das Format und nimmt die Zeichen vom Puffer. Deswegen mag ich scanf nicht, weil da ständig sowas passiert, wenn man nicht aufpasst. Deswegen benutze ich immer nicht fgets bzw. fgetc



  • void Ende(char *str)
    {
        size_t laenge;
        laenge = strlen(str);
        str[laenge-1]='\0'; //stimmt was nich...
    
    }
    

    ist str[laenge-1] nich sowieso schon ein '\0' ?
    wie wärs denn, wenn du dir das '\n' mit strrchr() raussuchst? es kann vorkommen, dass fgets das '\n' nicht miteinliest und du dann ein falsches zeichen löscht...

    wenn strrchr nichts gefunden hat, solltest du den eingabepuffer löschen, da die restlichen eingegebenen zeichen noch in stdin sind. (korrigiert mich da bitte, wenn ich falsch liege)

    EDIT:

    2. Was mich immernoch interesiert:
    Ich könnte die Eingabe der Datei bzw. des Pfades ja auch per scanf lösen! Aber dann taucht wieder dieses Problem auf! Kann mir das noch jemand erklären, wie ich das beseitige?

    wurde bereits geklärt...

    Jay schrieb:

    Nachdem ich den Namen bzw. Pfad der Datei angegeben habe unter Enter drücke, bringt er sofort "Name: Vorname:"!

    das kommt, weil du vergessen hast den eingabepuffer zu leeren.

    nochmals: siehe hier



  • Ich habe im Buch "C von A bis Z" nachgeschlagen und da war die Lösung mit laenge[p-1] drin!

    Denn ich hatte ja das Problem,dass er beim Reinschreiben immer einen Absatz gemacht hat! Und nach dem ich die Funktion implementiert habe, war der Absatz weg, also sollte es stimmen!

    Und du hast schon recht, dass das letzte zeichen eines char-arrays immer '\0' ist!
    Aber das char feld sieht ja dann so aus:

    Bsp.:
    'H' 'A' 'L' 'L' 'O' '\n' '\0'

    Dann wird eben die Länge berechnet und ein Element zurück gegangen und das wäre hier '\n', das zu '\0' geändert wird!



  • sheddy schrieb:

    Ich habe im Buch "C von A bis Z" nachgeschlagen und da war die Lösung mit laenge[p-1] drin!

    Denn ich hatte ja das Problem,dass er beim Reinschreiben immer einen Absatz gemacht hat! Und nach dem ich die Funktion implementiert habe, war der Absatz weg, also sollte es stimmen!

    Und du hast schon recht, dass das letzte zeichen eines char-arrays immer '\0' ist!
    Aber das char feld sieht ja dann so aus:

    Bsp.:
    'H' 'A' 'L' 'L' 'O' '\n' '\0'

    Dann wird eben die Länge berechnet und ein Element zurück gegangen und das wäre hier '\n', das zu '\0' geändert wird!

    sorry, war wohl doch ein bisschen zu schnell...
    strrchr() solltest du aber trotzdem besser nehmen 😉


Anmelden zum Antworten