struct in Datei speichern

Dieses Thema im Forum "C/C++" wurde erstellt von musiKk, 29.12.2006.

  1. #1 musiKk, 29.12.2006
    Zuletzt bearbeitet: 30.12.2006
    musiKk

    musiKk Dr. Strangelove

    Dabei seit:
    30.07.2006
    Beiträge:
    264
    Zustimmungen:
    0
    Ort:
    Leipzig
    struct in Datei speichern und inzwischen auch Auslesen...

    Hallo,
    sicher fuer viele ein Grund zum laecheln, bei mir klappts irgendwie nicht.
    Und zwar soll ich structs der folgenden Form abspeichern:
    Code:
    struct satztyp {
    	char name[20];
    	char vorname[20];
    	char anschrift[50];
    	char telefon[20];
    };
    
    Ich habe erst in der cppreference den Eintrag zu fwrite studiert und angewendet. Das lustige ist nur: In der FH auf der SUN laeuft das ganze wunderbar, hier zu Hause unter Linux stimmt nur "name", der Rest besteht nur aus sinnlosen Zeichen.
    Das wichtigste aus dem Code sollte dies sein:
    Code:
    void eingabe(char *dateiname) {
    	struct satztyp* neu;
    	neu=(struct satztyp*) malloc (sizeof(struct satztyp*));
    	printf("\n\n");
    	printf("--------------------------------\n");
    	printf("--  Neuen Datensatz eingeben  --\n");
    	printf("--------------------------------\n\n");
    
    	printf("Name: ");
    	scanf("%s",&(neu->name));
    	printf("Vorname: ");
    	scanf("%s",&(neu->vorname));
    	printf("Anschrift: ");
    	scanf("%s",&(neu->anschrift));
    	printf("Telefon: ");
    	scanf("%s",&(neu->telefon));
    	Fflush();
    	
    	FILE *fp=fopen(dateiname, "a");
    	fwrite(neu, sizeof(struct satztyp), 1, fp);
    	fclose(fp);
    }
    
    Fflush() ist eine Funktion, die den Puffer leert, da ich las, dass fflush(stdout) nicht immer funktionieren soll.
    Des weiteren habe ich auch mal statt scanf gets benutzt, da ich dies zuerst im Verdacht hatte, aber da kommt der gleiche Mist raus.

    Waere dankbar fuer nen Denkanstoss...
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. hehejo

    hehejo blöder Purist

    Dabei seit:
    12.10.2003
    Beiträge:
    1.280
    Zustimmungen:
    0
    Ort:
    Stein (Mittelfranken)
    Nun, zum ersten muss du nicht mit einem Pointer arbeiten.
    Das ist auch dein Fehler beim Rausschreiben.

    Dein Pointer neu zeigt genau auf den Anfang von char[20] name.
    fwrite wird auch wohl nur bis zum \0 schreiben.

    Also das könnte ich mir zumindest vorstellen.

    Vll. nützt dir das ja schon was.
     
  4. hwj

    hwj Doppel-As

    Dabei seit:
    23.06.2006
    Beiträge:
    131
    Zustimmungen:
    0
    Ort:
    Bei Buxtehude
    Zunächst ändere mal:

    neu=(struct satztyp*) malloc (sizeof(struct satztyp*));

    in

    neu=(struct satztyp*) malloc (sizeof(struct satztyp));

    Sonst liefert malloc Dir nur einen Speicherbereich von 4 Byte (je nach Pointergröße) zurück.

    Bei Deinem scanf ist das &(...) überflüssig und kann weggelassen werden da es (bei char-Arrays).

    fwrite schreibt genau das auf Platte was man der Funktion übergibt, ob ein \0 dabei ist, ist egal.

    Der Rest ist ***eigentlich*** ok, abgesehen davon, das sich mir die Nackenhaare sträuben, wenn man mit scanf in ein char-Array liest - wo schreib der hin, wenn der Benutzer mal ein en Namen mit 100 Zeichen eingibt :oldman :D

    Heiko
     
  5. musiKk

    musiKk Dr. Strangelove

    Dabei seit:
    30.07.2006
    Beiträge:
    264
    Zustimmungen:
    0
    Ort:
    Leipzig
    Ach herrjeh... warum habe ich das gemacht? Das habe ich doch sonst immer richtig gehabt?

    Ich bin mir nicht ganz sicher, aber ich glaube, das hat unter Solaris Probleme bereitet... vielleicht taeusche ich mich aber auch.

    Das glaube ich Dir gerne, ich werde das auch lieber mit fgets machen.

    Vielen Dank. :)
     
  6. musiKk

    musiKk Dr. Strangelove

    Dabei seit:
    30.07.2006
    Beiträge:
    264
    Zustimmungen:
    0
    Ort:
    Leipzig
    Ok, es geht weiter (wie zu erwarten). So langsam fuehle ich mich von dem IO-System von C gehoerig verarscht; staendig haengen irgendwelche Enterzeichen oder so im Puffer rum, ich flush mir nen Wolf. Aber das nur nebenbei...

    Problem ist jetzt: Wenn ich das Programm oeffne, eine neue Datei anlege (wobei der Name ueber ein Argument ODER innerhalt bestimmt wurde, das geht schonmal beides), da neue Datensaetze einfuege und diese dann auslesen will, klappt das wunderbar.
    Schliesse ich das Programm allerdings und oeffne es auf exakt die gleiche Weise, dann bekomme ich beim Auslesen einen Segmentation fault.

    Das wundert mich halt am meisten: Selbst wenn da noch irgendwelche anderen Fehler sind, wieso klappts bei naechsten Programmaufruf auf einmal nicht mehr? Wenns wenigstens NIE oder IMMER klappen wuerde, aber so...?

    Weiss einer Rat? :(

    (Funktion aendern() ist hier atm noch irrelevant, aber ich hab sie mal drin gelassen)

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define Fflush() while(getchar() != '\n')
    
    struct satztyp {
    	char name[20];
    	char vorname[20];
    	char anschrift[50];
    	char telefon[20];
    };
    
    char hauptmenue();
    void eingabe(char*);
    void ausgabe(char*);
    void aendern(char*);
    
    int main(int argc, char *argv[]) {
    	char *dateiname=(char*) malloc (20);
    	if(argc==1) {
    		printf("Keine Datei angegeben, bitte Dateiname angeben: ");
    		fgets(dateiname,20,stdin); dateiname[strlen(dateiname)-1]='\0';
    		Fflush();
    	} else {
    		dateiname=argv[1];
    	}
    	while(1) {
    		char auswahl;
    		auswahl=hauptmenue();
    		switch(auswahl) {
    			case '1': eingabe(dateiname); break;
    			case '2': ausgabe(dateiname); break;
    			case '3': aendern(dateiname); break;
    			default : exit(1);
    		}
    	}
    }
    
    char hauptmenue() {
    	char auswahl;
    	printf("-----------------------------------\n");
    	printf("--  Das hier ist das Hauptmenue  --\n");
    	printf("-----------------------------------\n\n");
    	printf("1 - Neuen Datensatz eingeben\n");
    	printf("2 - alle Datensaetze ausgeben\n");
    	printf("3 - Datensatz aendern\n");
    	printf("q - Beenden\n");
    	printf("Auswahl: ");
    	scanf("%s",&auswahl);
    	Fflush();
    	return auswahl;
    }
    
    void eingabe(char *dateiname) {
    	struct satztyp* neu;
    	neu=(struct satztyp*) malloc (sizeof(struct satztyp));
    	printf("\n\n");
    	printf("--------------------------------\n");
    	printf("--  Neuen Datensatz eingeben  --\n");
    	printf("--------------------------------\n\n");
    
    	printf("Name: ");
    	fgets(neu->name,20,stdin); neu->name[strlen(neu->name)-1]='\0';
    	printf("Vorname: ");
    	fgets(neu->vorname,20,stdin); neu->vorname[strlen(neu->vorname)-1]='\0';
    	printf("Anschrift: ");
    	fgets(neu->anschrift,50,stdin); neu->anschrift[strlen(neu->anschrift)-1]='\0';
    	printf("Telefon: ");
    	fgets(neu->telefon,20,stdin); neu->telefon[strlen(neu->telefon)-1]='\0';
    	Fflush();
    	FILE *fp=fopen(dateiname, "a");
    	fwrite(neu, sizeof(struct satztyp), 1, fp);
    	fclose(fp);
    	free(neu);
    }
    
    void ausgabe(char *dateiname) {
    	printf("\n\n");
    	printf("Nr.           Name        Vorname      Anschrift        Telefon\n");
    	printf("---------------------------------------------------------------\n");
    	FILE *fp=fopen(dateiname, "r");
    	struct satztyp* temp;
    	temp=(struct satztyp*) malloc (sizeof(struct satztyp));
    	int zaehler=1;
    	
    	while(fread(temp, sizeof(struct satztyp), 1, fp)) {
    		printf("%3d%15s%15s%15s%15s\n",zaehler, temp->name,temp->vorname,temp->anschrift,temp->telefon);
    		zaehler++;
    	}
    	free(temp);
    	fclose(fp);
    	printf("\n\n");
    }
    
    void aendern(char *dateiname) {
    	int auswahl, i;
    	struct satztyp* temp;
    	temp=(struct satztyp*) malloc (sizeof(struct satztyp));
    	FILE *fp=fopen(dateiname, "r+");
    	
    	ausgabe(dateiname);
    	printf("Welcher Datensatz soll geaendert werden?\n");
    	scanf("%d", &auswahl);
    	
    	for(i=1;i<auswahl;i++) {
    		fp++;
    	}
    	
    	struct satztyp* neu;
    	neu=(struct satztyp*) malloc (sizeof(struct satztyp));
    	printf("\n\n");
    	printf("--------------------------------\n");
    	printf("--     Datensatz aendern      --\n");
    	printf("--------------------------------\n\n");
    
    	printf("Name: ");
    	fgets(neu->name,20,stdin); neu->name[strlen(neu->name)-1]='\0';
    	printf("Vorname: ");
    	fgets(neu->vorname,20,stdin); neu->vorname[strlen(neu->vorname)-1]='\0';
    	printf("Anschrift: ");
    	fgets(neu->anschrift,50,stdin); neu->anschrift[strlen(neu->anschrift)-1]='\0';
    	printf("Telefon: ");
    	fgets(neu->telefon,20,stdin); neu->telefon[strlen(neu->telefon)-1]='\0';
    	Fflush();
    	
    	fwrite(neu, sizeof(struct satztyp), 1, fp);
    	fclose(fp);
    }
    
     
  7. hwj

    hwj Doppel-As

    Dabei seit:
    23.06.2006
    Beiträge:
    131
    Zustimmungen:
    0
    Ort:
    Bei Buxtehude
    Ooops - das ist nicht gut - mach besser einen int draus und %d, ebenso aus dem Rückgabewert von hauptmenü(). In dem switch mußt Du dann nicht nach '1', ... sondern nach 1 (als Zahl) ... fragen. Hier geht das dann ... alternativ kannst Du allerdings auch im hauptmenü in einen etwas größeren Array scanf'en:

    Heiko
     
  8. musiKk

    musiKk Dr. Strangelove

    Dabei seit:
    30.07.2006
    Beiträge:
    264
    Zustimmungen:
    0
    Ort:
    Leipzig
    Ja, naja... ich wollte doch aber noch nach 'q' fragen, weil ich 'q' zum Beenden nehmen wollte. Egal, ich hab noch ne Menge dran rumgefummelt... am meisten hat mich dann nochmal irritiert, dass jemand anders das unter Windows perfekt zum Laufen bekommen hat.

    Die Auswahl geht bei mir jetzt ueber getchar(). Und was soll ich sagen... SEITDEM gehts. Das Schreiben der Datei war ein Problem. Vorher war es Zufall, obs ging. Ich kanns mir einfach nicht erklaeren. Mal gabs Segmetation Faults, mal hiess meine Datei, wie ich sie nannte, mal war es einfach nur ein wilder Zeichenwust. Hier mal ein Beispiel.

    Mein naechstes Problem ist: Hier geht jetzt erstmal wirklich alles. Auch das Aendern. Allerdings nutzt mir das nix, weil ich das Programm in der FH auf ner SUN vorfuehren muss und DA geht das Aendern nicht! Ich glaub, ich krieg noch ganz viele graue Haare deswegen... :(
     
  9. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  10. hwj

    hwj Doppel-As

    Dabei seit:
    23.06.2006
    Beiträge:
    131
    Zustimmungen:
    0
    Ort:
    Bei Buxtehude
    Jaja, als ich vor vielen Jahren meine ersten C-Laufschritte gemacht habe, hatte ich ähnliche Probleme. Man muß erst mal "drin" sein, um richtig zu verstehen wie man Probleme angeht und lösen kann ...

    Oje, das sehe ich jetzt erst, habe die aendern Funktion noch nicht angesehen - allerdings möchte ich auch ungerne Deine Hausaufgabe machen :D

    Aber mal als Tipp: den Rückgabewert von fopen darfst Du auf keinen Fall mit ++ oder so ändern, dieser Wert zeigt auf eine "struct FILE" (oder wie auch immer "FILE" auf dem System implementiert ist). Ein "++" würde in einem Array von FILE-Strukturen auf die nächste Zeigen, bei Dir zeigt sie also anschließend ins Nirwada ...

    Also: "man fseek" oder alle Dummy-Sätze überlesen ...

    Viel Erfolg :headup:

    Heiko
     
  11. musiKk

    musiKk Dr. Strangelove

    Dabei seit:
    30.07.2006
    Beiträge:
    264
    Zustimmungen:
    0
    Ort:
    Leipzig
    Keine Sorge, niemand soll meine "Hausaufgaben" machen. ;)

    Das mit dem Filepointer kam mir auch spanisch vor, funktionierte aber glaub ich mal. Egal, ich mach das jetzt per fread(temp, sizeof(struct satztyp), 1, fp); (glaube, das ist auch das, was du mit "ueberlesen" meinst). Das wird halt so oft ausgefuehrt, bis man an der richtigen Stelle ist. Das ist zwar sicher auch nicht die tollste Variante, aber sie klappt zumindest unter Linux. Da Solaris wieder was voellig anderes draus macht, bin ich aber wohl gezwungen, mir fseek anzuschauen.

    Klar, bei mir wird kein Bereich ueberprueft, aber das sind fuer mich Feinheiten, die geringere Prioritaet haben.
     
Thema:

struct in Datei speichern

Die Seite wird geladen...

struct in Datei speichern - Ähnliche Themen

  1. Ausgabe in *.txt Datei & Struct

    Ausgabe in *.txt Datei & Struct: Hallo liebe Community! ;) Ich stehe vor einem kleinen Problem. Gegeben ist mein n-Damen auf dem Schachbrett-Programm. Nun stehe ich vor der...
  2. Core Infrastructure Initiative arbeitet an »Best Practices«-Abzeichen

    Core Infrastructure Initiative arbeitet an »Best Practices«-Abzeichen: Die von der Linux Foundation finanzierte »Core Infrastructure Initiative« will es leichter machen, unter der Vielzahl von freien Projekten...
  3. Core Infrastructure Initiative stellt Census-Projekt vor

    Core Infrastructure Initiative stellt Census-Projekt vor: Die von der Linux Foundation finanzierte »Core Infrastructure Initiative« hat damit begonnen, aktiv in der freien Softwarewelt nach Projekten zu...
  4. Core Infrastructure Initiative fördert drei Sicherheitsinitiativen

    Core Infrastructure Initiative fördert drei Sicherheitsinitiativen: Die von der Linux Foundation finanzierte »Core Infrastructure Initiative« hat jetzt drei weitere Projekte bekannt gegeben, die gefördert werden...
  5. Core Infrastructure Initiative der Linux Foundation startet

    Core Infrastructure Initiative der Linux Foundation startet: Im April hatte die Linux Foundation die »Core Infrastructure Initiative« angekündigt, die die Entwicklung und Wartung von kritischen freien...