SeppJ schrieb:
Allgemein krankt dein Programm an seiner Struktur
Das sehe ich nicht so, die Struktur ist OK.
- ein Objekt in main() definieren, das dann durch alle Funktionen herumgereicht wird
- prinzipielle Trennung von Oberflächen/Daten/Fehlerbehandlung/... Aktionen durch Funktionen
Die Implementierung ist aber grundsätzlich Schrott.
Was du brauchst ist eine (persistierte) Liste von struct-Elementen, das kann man - so wie du - direkt mit einem FILE-Stream machen, einfacher und somit weniger fehleranfällig ist es, eine dyn. Liste von struct zu verwenden, siehe Beispiel, und die reichst du dann herum.
Außerdem ist für deinen Fall eine textbasierte Datei unpraktisch, besser wäre eine Binärdatei, siehe Beispiel. Paddingbytes und Byteorder sind dabei zwar impl.abhängig von deinem Compiler/Laufzeitsystem, das kannst du aber erstmal ignorieren, solange du deine Datei ausschließlich in deinem System mit dem gleichen Compiler verwendest.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXILEN = 100 };
typedef struct {
char vname[MAXILEN];
char nname[MAXILEN];
char plz[MAXILEN];
char ort[MAXILEN];
int geburtsjahr;
} Adresse;
typedef struct {
int anzahl;
Adresse *liste;
} Liste;
void eintragSuchen(const Liste *liste) {
Adresse temp = { 0 };
printf("Eingabe von Nachnamen: ");
scanf("%99[^\n]", temp.nname); while (getchar() != '\n');
for(int i=0;i<liste->anzahl;++i) /* einfaches Suchen in der Liste im Speicher statt aufwändig mit fseek/fscanf in der Datei zu navigieren */
{
if (!strcmp(temp.nname, liste->liste[i].nname))
{
printf("Vorname %s ---", liste->liste[i].vname);
printf(" Nachname %s ---", liste->liste[i].nname);
printf("plz %s ---", liste->liste[i].plz);
printf("ort %s \n", liste->liste[i].ort);
printf("Jahr: %d \n", liste->liste[i].geburtsjahr);
}
}
}
/*
eine Adresse eingeben und hinten an die Liste (im Speicher!) anhängen
*/
void eintragEingeben(Liste *liste) {
Adresse temp = { 0 };
printf("Vorname : ");
scanf("%99[^\n]", temp.vname); while (getchar() != '\n');
printf("Nachname : ");
scanf("%99[^\n]", temp.nname); while (getchar() != '\n');
printf("Postleitzahl : ");
scanf("%99[^\n]", temp.plz); while (getchar() != '\n');
printf("Wohnort : ");
scanf("%99[^\n]", temp.ort); while (getchar() != '\n');
printf("Geburtsjahr : ");
scanf("%d", &temp.geburtsjahr); while (getchar() != '\n');
/* hinten an die Liste anhängen */
liste->liste = realloc(liste->liste, ++liste->anzahl * sizeof*liste->liste);
liste->liste[liste->anzahl - 1] = temp;
}
void menue(Liste *liste) {
while (1)
{
int a;
printf("----- Addresbuch ---- \n");
printf("----- W?hlen Sie eine Funktion ---- \n");
printf("1 - Eintragen \n");
printf("2 - Eintrag ausgeben \n");
printf("3 - Eintrag modifizieren \n");
printf("Auswahl:");
switch (scanf("%d", &a)==1?a:0) {
case 1: while (getchar() != '\n'); eintragEingeben(liste); break;
case 2: while (getchar() != '\n'); eintragSuchen(liste); break;
default: while (getchar() != '\n'); return;
}
}
}
void removeListe(Liste *l) { l->anzahl = 0; free(l->liste); }
void leseListe(Liste *liste, const char *datei)
{
FILE *f = fopen(datei, "rb");
if (f)
{
fread(&liste->anzahl, sizeof(int), 1, f);
liste->liste = realloc(liste->liste, liste->anzahl * sizeof*liste->liste);
fread(liste->liste, sizeof*liste->liste, liste->anzahl, f);
fclose(f);
}
}
void schreibeListe(const Liste *liste, const char *datei)
{
FILE *f = fopen(datei, "wb");
if (f)
{
fwrite(&liste->anzahl, sizeof(int), 1, f);
fwrite(liste->liste, sizeof*liste->liste, liste->anzahl, f);
fclose(f);
}
}
int main()
{
Liste liste = { 0 }; /* Arbeitsobjekt definieren und initialisieren */
leseListe(&liste, "adressen.dat"); /* befüllen aus Datei */
menue(&liste); /* Liste bearbeiten, Elemente hinzufügen... */
schreibeListe(&liste, "adressen.dat"); /* Liste persistieren */
removeListe(&liste); /* Listenspeicher freigeben */
return 0;
}