structure übergeben (Aufgabe Telefonliste)



  • Hey,

    ich habe folgendes Problem und zwar weiß ich nicht wie man in c eine Struktur übergeben kann. Vor einem Jahr habe ich für mein Studium eine Übungsaufgabe gemacht, wo wir eine Telefonliste in einer Struktur speichern kann. Damals habe ich mit einer globalen Struktur gearbeitet, mittlerweile ist die Übung etwas anders, und die Struktur soll in der Main Funktion festgelegt werden und dann an die anderen Funktionen übergeben werden. Ich bin leider schon ein bisschen aus C draußen und habe nicht mehr alles so im Kopf wie es funktioniert. Ich zeig euch einfach mal meinen Code, der gibt mir immer folgende Fehlermeldung "ein unvollständiger Typ ist nicht zulässig". Wie gesagt ich hatte es noch als globale Struktur, da hatte es so funktioniert, ein Freund brauchte jetzt Hilfe und die Aufgabenstellung erfordert nun, dass es übergeben werden soll. Und da war ich jetzt selber etwas verzweifelt. Wir haben schon vorher uns versucht in Google schlau zu machen, aber da steht auch immer nur in den Funktionsparametern (struct ...) Also ich weiß nicht was bei mir falsch ist, warum es nicht funktioniert, ich wäre dankbar wenn ihr mir helfen könnt 😉

    Hier ist mein Code

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define   MAX_Anzahl 30
    
    void Eingabe (int i, struct eintrag telefonliste)
    {
    	if (i <= 30)
    	{
    	printf ("Name:");
    	scanf ("%s", telefonliste[i].name);
    	printf ("Vorname:");
    	scanf ("%s", telefonliste[i].vorname);
    	printf ("Tel-Nr.:");
    	scanf ("%s", telefonliste[i].nummer);
    	i++;
    	}	
    	else 
    	{printf ("Liste voll");}
    
    }
    
    void Ausgabe(int i, struct eintrag telefonliste)
    {
    	int x;				//Nummernzähler
    	printf  ("Nr.  Name                       Vorname                 Tel-Nr.");
    	for (x=0;x < i+0;x++)
    	{
    	printf("\n%-5d", x+1);
    	printf("%-27s", telefonliste[x].name);
    	printf("%-24s", telefonliste[x].vorname);
    	printf("%-15s", telefonliste[x].nummer);
    	}
    
    }
    void Löschen(int i, struct eintrag telefonliste)
    {
    	int löschen;
    	printf ("Nummer des zu löschenden Datensatzes eingeben:");
    	scanf ("%d", &löschen);
    	if ((i > löschen) && (löschen != 0))
    	{
    		do
    		{
    		telefonliste[löschen-1] = telefonliste[löschen];
    		löschen++;
    		}
    		while (löschen < i);
    		i--;
    	}
    
    }
    
    int main ()
    {
    	int i = 0;			//Zähler für die Datensätze, belegte Plätze insgesamt
    
    	struct eintrag
    	{
    		char name[20];
    		char vorname[15];
    		char nummer[15];
    	};
    	static struct eintrag telefonliste[MAX_Anzahl];
    
    	int Menü;
    
    	do
    	{
    
    	printf ("\n\nBitte waehlen Sie: \n\n1 - neuen Teilnehmer eingeben\n2 - Telefonliste ausgeben\n3 - Teilnehmer löschen\n4 - Programm beenden\n\nAuswahl:"); 
    	scanf ("%d", &Menü);
    	if (Menü == 1)
    	{Eingabe(i,telefonliste);}
    	if (Menü == 2)
    	{Ausgabe(i,telefonliste);}
    	if (Menü == 3)
    	{Löschen(i,telefonliste);}
    	if (Menü == 4)
    	{return 0;}
    	getchar();
    	}
    	while (Menü <= 9);
    }
    


  • Du erstellst einen Zeiger der Struktur und übergibst ihn den Funktionen.
    In den Funktionen schreibst du dann:

    void Eingabe (int i, eintrag **telefonliste)
    

    Die Struktur an sich musst du dann aber außerhalb der main schreiben.

    typedef struct
    {
        char name[20];
        char vorname[15];
        char nummer[15];
    }
    eintrag;
    


  • Danke auf jedenfall schonmal für die Antwort mit dem Zeigen, aber muss man das außerhalb von main schreiben ? Wie gesagt ich hatte das früher auch so als globale, aber dann musste man die struct doch allgemein nicht übergeben oder ? weil dann kann man doch sowieso darauf zugreifen.

    Jetzt in der Aufgabenstellung ist gefordert die sollen in der main definiert werden

    " Das Feld mit den Einträgen sowie die aktuelle Anzahl der Einträge sollen als Variablen im
    Hauptprogramm definiert werden:
    static struct eintrag liste[MAX_ANZAHL];
    int anzahl=0;"



  • int main (void)
    {
        int i = 0;/*Zähler für die Datensätze, belegte Plätze insgesamt */
        int j;
        int Auswahl;
    
        eintrag *telefonliste[MAX_ANZAHL];
        for (j=0; j<MAX_ANZAHL; j++)
            telefonliste[j] = malloc(sizeof(eintrag));
    
        do
        {
            printf ("\n\nBitte waehlen Sie: \n\n1 - neuen Teilnehmer eingeben\n2 - Telefonliste ausgeben\n3 - Teilnehmer loeschen\n4 - Programm beenden\n\nAuswahl:");
            scanf ("%d", &Auswahl);
            if (Auswahl == 1)
                Eingabe(i,telefonliste);
            if (Auswahl == 2)
                Ausgabe(i,telefonliste);
            if (Auswahl == 3)
                Loeschen(i,telefonliste);
            if (Auswahl == 4)
                exit(0);
            getchar();
        }
        while (Auswahl <= 9);
        for (i=0; i<MAX_ANZAHL; i++)
            free(telefonliste[i]);
        return 0;
    }
    
    typedef struct
    {
        char name[20];
        char vorname[15];
        char nummer[15];
    }
    eintrag;
    

    Den Rest musst du entsprechend abändern.



  • Eine struct kannst du wie eine einfache Variable an Funktionen über- und zurückgeben.

    In den allerersten C Versionen (vor C89) ging das noch nicht.

    Man sollte allerdings bedenken, dass die Kopieroperation Performence kostet.

    Du hast aber ein Array einer struct . Und dann hast du ein Array.

    Der Index bei einem Array fängt bei 0 an. Immer.
    Wenn du 30 Elemente hast, ist der letzte gültige Index 29



  • Alle deine Funktionen benötigen die Daten des Arrays, also musst du das immer übergeben.
    Ebenso solltest du immer auch den aktuellen Füllungsgrad des Arrays übergeben, da dieser sich innerhalb der Funktion ändern kann (bei Eingabe+Loeschen) per Zeiger:

    void Eingabe(int *i, struct eintrag *telefonliste)
    {
        if (*i >= MAX_Anzahl) return;
    
        printf ("Name:");
        scanf ("%19s", telefonliste[*i].name);
        printf ("Vorname:");
        scanf ("%14s", telefonliste[*i].vorname);
        printf ("Tel-Nr.:");
        scanf ("%14s", telefonliste[*i].nummer);
    
        ++*i; 
    }
    
    struct eintrag telefonliste[MAX_Anzahl];
    int i = 0;
    ...
    printf("%d",i);
    Eingabe(&i, telefonliste);
    printf("%d",i);
    


  • Domooo93 schrieb:

    [...]Damals habe ich mit einer globalen Struktur gearbeitet, mittlerweile ist die Übung etwas anders, und die Struktur soll in der Main Funktion festgelegt werden und dann an die anderen Funktionen übergeben werden.[...]

    Bist du sicher das du die struct in der main definieren sollst? Meiner Meinung ist diese struct dann auch nur in der main bekannt und in den anderen Funktionen unbekannt, daher auch der Fehler mit dem unvollständigen Typ. Aber IMHO

    Domooo93 schrieb:

    Ich bin leider schon ein bisschen aus C draußen und habe nicht mehr alles so im Kopf wie es funktioniert. Ich zeig euch einfach mal meinen Code, der gibt mir immer folgende Fehlermeldung "ein unvollständiger Typ ist nicht zulässig". Wie gesagt ich hatte es noch als globale Struktur, da hatte es so funktioniert, ein Freund brauchte jetzt Hilfe und die Aufgabenstellung erfordert nun, dass es übergeben werden soll.

    Ja, global, dann ist sie auch für die anderen Funktionen sichtbar. Sie muss vor der ersten Benutzung schon bekannt sein, genauer wenn man auf member zugreifen will. Und genau das machst du. Innerhalb der Funktionen greifst du auf member von 'eintrag' zu. struct eintrag ist aber nur für main() bekannt. Für 'Loeschen' z.b. ist das ein unvollständiger Typ. Dasselbe wäre wenn du die Funktionen unter main() schreiben würdest und vor sie vor main() vorwärts-deklarieren würdest.

    Theoretisch müstest du jetzt (Achtung Stuss!) die struct eintrag jeweils im
    Funktionskopf definieren (in allen!):

    void Eingabe (int i, struct eintrag {char name[20]; char vorname[15]; char nummer[15];} telefonliste)
    { [...]
    

    Aber ich weiß nicht ob das geht, glaub aber schon, ist ja C und kein wasweisich Pascal. Aber es würden doch zumindest Warnungen
    kommen weil es nach Meinung des Compilers zwei verschiedene 'struct eintrag' sind und daher seiner Meinung nach auch nicht kompatibel. Über den selben Namen 'eintrag' wird er sich aber nicht aufregen da beide 'struct eintrag' in verschiedenen Gültigkeitsbereichen definiert sind. Aber wie gesagt, sowas ist Stuss...

    Ich glaube dein Prof/Dozent/Whatever wollte das du ein array von dieser struct als lokale Variable in main hast. Die definition der struct aber global. Alles andere wäre für mich sinnlos...

    Ansonsten gilt das was die anderen geschrieben haben. int i ist z.B. nur in main bekannt, sie bleibt immer 0. Die anderen i's (DeppenA. mit Absicht) sind lokal zu den jeweiligen Funktionen, sie beeinflussen int i in main nicht... Ich hab mir den Code jetzt nicht genau angeschaut, mir viel nur dieses Detail auf und ich habe mich gefragt warum dich keiner darauf aufmerksam gemacht hat. Daher: könnte auch sein das ich falsch liege.

    Ich selbst hab es mehr mit C++ daher keine Ahnung ob du da besser typdef struct {bla} eintrag; ... oder nur struct eintrag {bla} machst, hab den Unterschied selbst nie wirklich begriffen...

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define   MAX_Anzahl 30
    
    // Hier die struct hin.
    
    void Eingabe (int i, struct eintrag telefonliste)
    {
    	if (i <= 30)
    	{
    	printf ("Name:");
    	scanf ("%s", telefonliste[i].name);
    	printf ("Vorname:");
    	scanf ("%s", telefonliste[i].vorname);
    	printf ("Tel-Nr.:");
    	scanf ("%s", telefonliste[i].nummer);
    	i++;
    	}	
    	else 
    	{printf ("Liste voll");}
    
    }
    
    void Ausgabe(int i, struct eintrag telefonliste)
    {
    	int x;				//Nummernzähler
    	printf  ("Nr.  Name                       Vorname                 Tel-Nr.");
    	for (x=0;x < i+0;x++)
    	{
    	printf("\n%-5d", x+1);
    	printf("%-27s", telefonliste[x].name);
    	printf("%-24s", telefonliste[x].vorname);
    	printf("%-15s", telefonliste[x].nummer);
    	}
    
    }
    void Löschen(int i, struct eintrag telefonliste)
    {
    	int löschen;
    	printf ("Nummer des zu löschenden Datensatzes eingeben:");
    	scanf ("%d", &löschen);
    	if ((i > löschen) && (löschen != 0))
    	{
    		do
    		{
    		telefonliste[löschen-1] = telefonliste[löschen];
    		löschen++;
    		}
    		while (löschen < i);
    		i--;
    	}
    
    }
    
    int main ()
    {
    	int i = 0;			//Zähler für die Datensätze, belegte Plätze insgesamt
    
    // Das nach oben VOR allen Funktionen die sie benutzen...
    //	struct eintrag
    //	{
    //		char name[20];
    //		char vorname[15];
    //		char nummer[15];
    //	};
    	static struct eintrag telefonliste[MAX_Anzahl];
    
    	int Menü;
    
    	do
    	{
    
    	printf ("\n\nBitte waehlen Sie: \n\n1 - neuen Teilnehmer eingeben\n2 - Telefonliste ausgeben\n3 - Teilnehmer löschen\n4 - Programm beenden\n\nAuswahl:"); 
    	scanf ("%d", &Menü);
    	if (Menü == 1)
    	{Eingabe(i,telefonliste);}
    	if (Menü == 2)
    	{Ausgabe(i,telefonliste);}
    	if (Menü == 3)
    	{Löschen(i,telefonliste);}
    	if (Menü == 4)
    	{return 0;}
    	getchar();
    	}
    	while (Menü <= 9);
    }
    

Anmelden zum Antworten