Hilfe bei Warenkorb
-
Hallo. Und zwar muss ich fürs Studium ein Warenhaus in C programmieren. Ist vom Grunde her eigentlich auch alles kein Problem, ABER: Es soll möglich sein neue Nutzer anzulegen und diese in einer Datei zu speichern.
Folgende Daten sollen gespeichert werden:
- Name
- Vorname
- Strasse
- Hausnummer
- PLZ
- Ort
- Vorwahl
- TelefonHierbei ist mir folgendes klar:
- Name, Vorname, Strasse und Ort sind mit fgets zwecks leerzeichen einzulesen
- PLZ, Vorwahl und Telefon ist alles möglich als long bzw. integer zu speichern
Die frage die dabei bleibt ist: Was machen wir mit der Hausnummer, denn es könnte ja z.B. 7 b sein.Aber mein eigentliches Problem liegt eigfentlich darin wie ich die datei wieder so auslese das alle Daten dort in der Struktur ankommen wo sie hingehören.
ich habe hier mal das was ich bis jetzt dazu habe. Würde mich freuen wenn mir schnell jemand helfen könnte.#define MAX 40 struct benutzer { char name[MAX]; char vorname[MAX]; char strasse[MAX]; /*int nr; char buchstabe; long plz; char ort[MAX]; char vorwahl[MAX]; char telefon[MAX]; char zusatz1_vor[MAX]; char zusatz1_tel[MAX];*/ struct benutzer *next; }; struct benutzer *next = NULL; struct benutzer *anfang = NULL; void anhaengen(char *nach, char *vor, char *str) { struct benutzer *zeiger; if(anfang == NULL) { if((anfang = (struct benutzer *) malloc(sizeof(struct benutzer))) == NULL) { fprintf(stderr, "Kein Speicherplatz vorhanden " "für anfang\n"); return; } strcpy(anfang->name, nach); strcpy(anfang->vorname, vor); strcpy(anfang->strasse, str); /* anfang->nr = num; anfang->buchstabe=buch; anfang->plz = post; strcpy(anfang->ort, stadt); strcpy(anfang->vorwahl, vwahl); strcpy(anfang->telefon, tel);*/ anfang->next=NULL; } else { zeiger=anfang; /* Wir zeigen auf das 1. Element */ while(zeiger->next != NULL) zeiger=zeiger->next; if((zeiger->next =(struct benutzer *) malloc(sizeof(struct benutzer))) == NULL) { fprintf(stderr,"Kein Speicherplatz für das " "letzte Element\n"); return; } zeiger=zeiger->next; /* zeiger auf neuen Speicherplatz */ strcpy(zeiger->name, nach); strcpy(zeiger->vorname, vor); strcpy(zeiger->strasse, str); /* zeiger->nr = num; zeiger->buchstabe=buch; zeiger->plz = post; strcpy(zeiger->ort, stadt); strcpy(zeiger->vorwahl, vwahl); strcpy(zeiger->telefon, tel);*/ zeiger->next=NULL; } } void eingabe(void) { char nam[MAX],vorn[MAX],strasse[MAX],ort[MAX],vorw[MAX],tel[MAX],buchst; int nr,buchst_j_n; long plz; clrscr(); printf("\nEingabe eines neuen Nutzers\n--------------------------------\n\n"); fflush(stdin); printf("Name........................: "); //scanf("%s",&nam); fgets(nam, MAX, stdin); fflush(stdin); printf("Vorname.....................: "); //scanf("%s",&vorn); fgets(vorn, MAX, stdin); fflush(stdin); printf("Strasse (ohne Nummer).......: "); //scanf("%s",&strasse); fgets(strasse, MAX, stdin); /* do { fflush(stdin); printf("Hausnummer (ohne Buchstabe): "); scanf("%d",&nr); }while((nr<1)|(nr>1000));*/ nam[strlen(nam)-1]=""; vorn[strlen(vorn)-1]=""; strasse[strlen(strasse)-1]=""; anhaengen(nam, vorn, strasse); fflush(stdin); printf("\n\nDaten gespeichert. Weiter mit [ENTER]"); getchar(); } void speichern(void) { struct benutzer *zeiger = anfang; FILE *datei; datei = fopen("benutzer.db", "w"); while(zeiger != NULL) { fprintf(datei,"%s %s %s %d\n", zeiger->name,zeiger->vorname,zeiger->strasse); zeiger=zeiger->next; } fclose(datei); } void dat_einlesen(void) { char nam[MAX],vorn[MAX],strasse[MAX],ort[MAX],vorw[MAX],tel[MAX],buchst; int nr; long plz; FILE *datei; datei = fopen("benutzer.db", "r"); if(datei != NULL){ while(!feof(datei)){ fflush(stdin); fgets(nam, MAX, datei); fgets(vorn, MAX, datei); fgets(strasse, MAX, datei); //fgets(nr,MAX,datei); anhaengen(nam, vorn, strasse); } } /*else{ printf("Fehler beim Öffnen der Datei"); }*/ fclose(datei); } void ausgabe(void) { struct benutzer *zeiger = anfang; while(zeiger != NULL) { printf("%s %s %s %d\n", zeiger->name,zeiger->vorname,zeiger->strasse); zeiger=zeiger->next; } printf("\n"); }
PS: Wem das jetzt zu schlecht erklärt ist kann sich mal unter http://www.htw-dresden.de/~wacker/SS05/WWW-Seite_PinC/pdf/Praktikum/Belegaufgabe.pdf die genaue Aufgabe anschauen um etwas dahinter zu blicken.
MfG
Tazz85
-
Wenn du bei der Dateiarbeit auf "Binäres Schreiben" und "Binäres Lesen" setzt gehts einfacher.
Die datei in die du schreibst ist aber hinterher nicht mehr so einfach lesbar ueber ein Texteditor."Binäres Schreiben" geht mit
fwrite(...);
"Binäres Lesen" geht mit
fread(...);
das spart ne Menge Code! Und ist besonders zu empfehlen zum lesen und schreiben ganzer Strukturen in/aus eine Datei!
Wenn Du diese Variante nutzen willst mach aber aus deiner Struktur 2 Strukturen!
Eine als Listenknoten nur um die einfach verkettet Kiste aufzubauen.
Und die andere zum Speichern der daten auf die es wirklich ankommt.
Denn sonst schreibst du beim "Binären Schreiben" die Zeigeraddress mit in die Datei was völlig sinnlos ist!Hier mein Beispiel was Dir als Ansatz helfen kann:
#include <stdio.h> #include <stdlib.h> #define MAX 100 /* Eigentlichen Nutzerdaten aus dem Listenknoten entkoppelt, sonst speichert man bei Anwendung von "fwrite" völlig sinnlos die Zeigeraddresse vom Element "next" */ struct nutzer { char name[MAX]; char vorname[MAX]; }; void ausgabe(struct nutzer n); { printf("%s\n%s\n", n.name, n.vorname); } struct benutzer { struct nutzer n; struct benutzer *next; }; int main(int argc, char *argv[]) { FILE *fp = NULL; // 2 Strukturvariablen vom Typ "nutzer anlegen" struct nutzer an, bn = { "Mustermann", "Peter", }; // Nutzerdaten ausgeben ausgabe(bn); // Eine Datei zur Speicherung der Nutzerdaten öffnen fp = fopen("nutzer.dat","w"); // die Daten in die Datei schreiben (Binär speichern) if(fp) fwrite((const void *) &bn, sizeof(struct nutzer), 1, fp); // Datei schliessen fclose(fp); // Strukturvariable leeren memset((const void *) &bn, 0, sizeof(struct nutzer)); // Ausgabe um zu gucken obse wirklich leer ist ausgabe(bn); // Datei zum lesen öffnen fp = fopen("nutzer.dat","r"); // Eine Struktur aus Datei lesen (Binäres lesen) if(fp) fread((void *) &an, 1, sizeof(struct nutzer), fp); // Datei schliessen fclose(fp); // Daten nach dem Auslesen aus Datei wieder anzeigen ausgabe(an); getchar(); return 0; } void ausgabe(struct nutzer n) { printf("%s\n%s\n", n.name, n.vorname); }
MFG
-
Das vereinfacht dann gleichzeitig auch deine Untermodule zur Listenverwaltung erheblich!!!!
MFG
-
Das Problem in deiner Ascii war folgendes:
Durch das %s schreibst du nur die Zeichen bis \0 und nicht MAX Zeichen pro String und liest ihn dann mit MAX Zeichen ein, das kann nicht funktionieren//schreiben fprintf(datei,"%s %s %s %d\n", zeiger->name,zeiger->vorname,zeiger->strasse); zeiger=zeiger->next; //Lesen fgets(nam, MAX, datei); fgets(vorn, MAX, datei); fgets(strasse, MAX, datei);
Lösung 1 Du schreibst jeden String mit Maxlänge in die Datei, dann kannst du ihn mit deinem fgets lesen, hat aber nach dem lesen unnötige leerzeichen am Ende des Strings
#define MAX 25 fprintf(datei,"%25s%25s%25s%6d",
Lösung 2 Du schreibst jeden String mit \n in die Datei, da fgets bei \n das lesen beendet liest deine bestehende Lesesequenz die Strings aus dem File aus
#define MAX 25 fprintf(datei,"%25s%25s%25s%6d",
Lösing 3 Du Schreibst binaer,
Vorteil
kompakterer Code,
Nachteil
1 Änderungen an der Struktur erzeugen einen hohen Aufwand, da das komplette Datenfile reorganisiert werden muss.
2 es werden immer die Maximalzahl der Bytes geschrieben, das kann bei vielen Daten zu einer hohen Platzverschwendung führen, da ja die jeweiligen Einzelelemente am längst möglichen Eintrag orientiert werden müssen.