Speicherzugriffsfehler bei Adressbuch



  • Hallo!

    Ich habe mich mal eben hingesetzt, und wollte ein typisches Adressbuch schreiben.

    So weit bin ich schon:

    /*
    	Programm: Personal Manager
    	Autor: LastManStanding
    
    	Programmiersprache: C
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    
    /*
    	Es folgen Elemente zur verwaltung der Kommandozeilenargumente
    	bestehend aus: enum arguments - enthaelt Konstanten,
    	die ein bestimmtes Komandozeilenargument darstellen
    
    	enum arguments getArg(char *arg) - erwartet einen C - String,
    	und gibt dann zurueck um welches Argument es sich handelt. Der
    	Rueckgabetyp ist eine Konstante aus dem enum arguments 
    */
    enum arguments
    {
    	UNKNOWN = 0, VERSION = 1, AUTHOR = 2, INFO = 3
    };
    
    // getArg wertet die Argumente aus, die das Programm erhaelt!
    enum arguments getArg(char *arg)
    {
    	enum arguments arg1 = UNKNOWN;
    
    	if(arg[0] == '-')
    	{
    		if(arg[1] == 'v') arg1 = VERSION;
    		if(arg[1] == 'a') arg1 = AUTHOR;
    		// Weitere Argumente folgen noch
    	}
    
    	return arg1; 
    }
    
    /* 
    	Es folgen die benoetigten Strukturen, und die dazugehoerigen Funktionen.
    
    	Ich habe zum aendern eines jeden Elements der Struktur Kontakt
    	eine eigene Funktion erstellt, um dann bequem zu jedem Zeitpunkt
    	ein einzelnes Elemente aus der Struktur veraendern zu koennen
    */
    struct Kontakt
    {
    	char *vorname;
    	char *nachname;
    	char *adresse;
    	char *tel;
    };
    
    struct Adressbuch
    {
    	struct Kontakt kontakt[20];
    };
    
    int addKontakt(struct Adressbuch *aBuch,
    	       const char *vorname,
    	       const char *nachname, 
    	       const char *adresse, 
    	       const char *tel)
    {
    	printf("So weit so gut!\n");
    	changeVorname(aBuch->kontakt[0], vorname);
    	printf("Vorname: OK!\n");
    	changeNachname(aBuch->kontakt[0], nachname);
    	printf("Nachname: OK!\n");
    	changeAdresse(aBuch->kontakt[0], adresse);
    	printf("Adresse: OK!\n");
    	changeTel(aBuch->kontakt[0], tel);
    	printf("Telefonnummer: OK!\n");
    
    	return 0;
    }
    
    int changeVorname(struct Kontakt *kon, const char *vorname)
    {
    	strcpy(kon->vorname, vorname);
    	return 0;
    }
    
    int changeNachname(struct Kontakt *kon, const char *nachname)
    {
    	strcpy(kon->nachname, nachname);
    	return 0;
    }
    
    int changeAdresse(struct Kontakt *kon, const char *adresse)
    {
    	strcpy(kon->adresse, adresse);
    	return 0;
    }
    
    int changeTel(struct Kontakt *kon, const char *tel)
    {
    	strcpy(kon->tel, tel);
    	return 0;
    }
    
    int printKontakt(struct Kontakt *kon)
    {
    	printf("%s %s\t%s Tel.: %s", kon->vorname, kon->nachname, kon->adresse, kon->tel);
    	return 0;
    }
    
    int sortKontakte(struct Adressbuch *aBuch)
    {
    	// TODO: Hier werden die Kontakte nach den Nachnamen sortiert
    	return 0;
    }
    
    //	Nun folgt der Hauptteil des Programmes
    int main(int argc, char **argv)
    {
    	// Parameter Verwaltung
    	int i = 1;
    	enum arguments argument;
    	while(i < argc)
    	{
    		argument = getArg(argv[i]);
    
    		if(argument == VERSION) printf("Version: 0.0.1\n");
    		if(argument == AUTHOR) printf("Von: Zahrer Alexander\n");
    		if(argument == UNKNOWN) printf("Unbekannter Parameter: %s!\nProgramm gestoppt!\n", argv[i]);
    		i++;
    	} 
    	if(argc >= 2) return 0;// Ende der Parameterverwaltung
    
    	char *vor;
    	char *nach;
    	char *adr;
    	char *tel;
    
    	struct Adressbuch adrBuch;
    
    	printf("Eingabe: ");
    	scanf("%s %s %s %s", &vor, &nach, &adr, &tel);
    
    	addKontakt(&adrBuch, vor, nach, adr, tel);
    	printKontakt(&adrBuch.kontakt[0]);
    
    	return 0;
    }
    

    Nun bekomme ich jedesmal wenn ich das Programm ohne Argumente aufrufe einen Speicherzugriffsfehler.

    mfg LastManStanding



  • da muß ich ja gleich mal gewaltig den rotstift ansetzen 😃

    char *vor; 
    char *nach; 
    char *adr; 
    char *tel; 
    
    struct Adressbuch adrBuch; 
    
    printf("Eingabe: "); 
    scanf("%s %s %s %s", &vor, &nach, &adr, &tel);
    

    hier fehlt der speicher, in den du die eingabe einlesen willst! vor,nach etc sind ja nur zeiger, die auf nix zeigen. es müßte so heißen:

    char vor[128]; 
    char nach[128]; 
    char adr[128]; 
    char tel[128]; 
    
    struct Adressbuch adrBuch; 
    
    printf("Eingabe: "); 
    scanf("%s %s %s %s", vor, nach, adr, tel);
    

    jetzt sinds char-arrays, die für bis zu 127 zeichen lange c-strings mit nul-byte platz bieten. statt 128 kannst du natürlich auch eine andere größe verwenden. die brezel vor den scanf()-argumenten kannst du auch weglassen. wenn du bei arrays nur den namen schreibst, nimmt c automatisch den zeiger.

    struct Kontakt 
    { 
        char *vorname; 
        char *nachname; 
        char *adresse; 
        char *tel; 
    };
    

    das selbe problem. deine struktur kontakt enthält nur zeiger aber keinen speicher für die strings. das müßte so heißen:

    struct Kontakt 
    { 
      char vorname[128]; 
      char nachname[128]; 
      char adresse[128]; 
      char tel[128]; 
    };
    

    auch hier kannst du anstelle von 128 die größe einsetzen, die deine strings brauchen.

    int addKontakt(struct Adressbuch *aBuch, 
               const char *vorname, 
               const char *nachname, 
               const char *adresse, 
               const char *tel) 
    { 
        printf("So weit so gut!\n"); 
        changeVorname(aBuch->kontakt[0], vorname); 
        printf("Vorname: OK!\n"); 
        changeNachname(aBuch->kontakt[0], nachname); 
        printf("Nachname: OK!\n"); 
        changeAdresse(aBuch->kontakt[0], adresse); 
        printf("Adresse: OK!\n"); 
        changeTel(aBuch->kontakt[0], tel); 
        printf("Telefonnummer: OK!\n"); 
    
        return 0; 
    }
    

    also das mit changeVorname() etc haut auch nicht hin, da du keinen zeiger auf kontakt übergibst, wie es changeVorname() verlangt, sondern die kontakt-struktur selbst. der compiler sollte da eigentlich einen fehler melden. du mußt also überall vor aBuch->kontakt[0] ein '&' setzen.

    das was glaub ich. ansonsten sieht dein code eigentlich ganz zivilisiert aus 👍



  • @LastManStanding
    RESPECT bis auf den kleinen fehler mit den zeigern echt eleganter code haette von mir sein koennen 😃



  • OK Danke für die Hilfe.

    mfg LastManStanding


Anmelden zum Antworten