Daten aus Struktur-Array in neuen Struktur Arry kopieren



  • Hi, ich möchte einen simple nKatalog programmieren, wo man Artikel eingeben kann, anzeigen lassen kann, eine Bestellung aufnehmen kann und diese anzeigen lassen kann. Die ersten beiden Sachen funktionieren auch. Beim Bestellung aufnehmen hänge ich...
    Ich möchte im Katalog nach einer Bestellnummer suchen: funktioniert!
    Wenn er sie gefunden hat, soll er sie in den Bestell-Struktur-Array kopieren: funktioniert nicht!

    Könnt ihr euch mein Quellcode mal anschauen und mir sagen was ich falsch mache bitte, ich bin ewig am rumprobieren, nichtmal eine deklarierte Ganzzahl lässt sich in den Struktur-Array schreiben.

    # include <stdio.h>
    # include <string.h>
    # include <stdlib.h>
    
    // Funktion vom Typ "struct mat", um neue Produkte einzufügen
    struct mat *neumat(int);
    
    // Neue Struktur des Katalogs festlegen
    struct mat {	
    			int bestellnummer; 
    			char produktbezeichnung[20];
    			double preis;
    			}*katalog[20];					// Array mit Platz für 20 Pointer, die auf den Typ struct mat zeigen
    
    // Funktionsprototyp um Bestellung aufzunehmen
    struct bestell *aufnehmen(int , int);
    
    // Neue Struktur der Bestellung festlegen
    struct bestell {
    				int anz;
    				struct mat *produkt;
    				double gesamt;
    				}*bestellung[20];			// Array mit Platz für 20 Pointer, die auf den Typ struct bestell zeigen
    
    // Funktion, um Katalog anzuzeigen
    void listeanzeigen(int);
    
    // Funktion, um Bestellung anzuzeigen
    //void bestellunganzeigen(int);
    
    int main ()
    {
    	int auswahl=1, i=0, j=0, anzahl=0, anzahl2=0;
    
    	printf("\nHAW Versand AG\n");
    
    	while(auswahl!=0)
    	{
    		printf("\n================================\n");
    		printf("1: neues Produkt eingeben\n");
    		printf("2: Katalog Anzeigen\n");
    		printf("3: Bestellung aufnehmen\n");
    		printf("4: Bestellung anzeigen\n");
    		printf("0: Ende\n");
    		printf("================================\n");
    
    		printf("Auswahl: ");
    
    		fflush(stdin);
    
    		if(scanf("%d", &auswahl)==0)  // Ungültige Eingabe abfangen
    			auswahl=9;
    
    		printf("\n");
    
    		switch(auswahl)
    		{
    			// Ende bei 0
    			case 0:
    				printf("Katalog beendet\n\n");
    				break;
    
    			// Neues Produkt eingeben
    			case 1:
    
    				*neumat(anzahl);
    				anzahl++;
    
    				break;
    
    			// Katalog anzeigen
    			case 2:
    
    				printf("Best-Nr\t%-20s %5s\n", "Bezeichnung", "Preis");
    				printf("----------------------------------\n");
    
    				for(i=0;i<anzahl;i++)
    
    					listeanzeigen(i);
    
    				printf("----------------------------------\n");
    				break;
    
    			// Bestellung aufnehmen
    			case 3:
    
    				*aufnehmen(anzahl, anzahl2);
    				anzahl2++;
    
    				break;
    
    			// Bestellung anzeigen
    			case 4:
    
    				printf("Anz. Best-Nr\t%-20s%6s%6s\n", "Bezeichnung", "E-Preis", "Summe");
    				printf("----------------------------------\n");
    
    				for(j=0;j<anzahl;j++)
    
    					//bestellunganzeigen(j);
    
    				printf("----------------------------------\n");
    				break;
    
    			default:
    
    				printf("Ungueltige Eingabe!\n\n");
    				break;
    
    		}
    	}
    }
    
    // Funktion vom Typ "struct mat", um neue Produkte einzufügen
    struct mat *neumat(int x)
    {
    	// Speicher in Katalog um die Größe von einer "struct mat" erweitern.
    	katalog[x] = malloc(sizeof(struct mat));
    
    	// Speichert die Ganzahl Bestellnummer bei der ersten(usw.) Eingabe an der ersten(usw.) Stelle Bestellnummer im Katalog
    	printf("Bestell-Nummer: "); scanf("%i", &(katalog[x]->bestellnummer));
    
    	printf("Produktbezeichnung: "); scanf("%s", katalog[x]->produktbezeichnung);
    
    	printf("Preis: "); scanf("%lf", &(katalog[x]->preis));
    }
    // Funktion zur Ausgabe des Katalogs
    void listeanzeigen(int n)
    {
    	printf("%7.d", (katalog[n]->bestellnummer));
    	printf("\t%-20s", katalog[n]->produktbezeichnung);
    	printf("%6.2lf\n", (katalog[n]->preis));
    }
    // Funktion zu Aufnahme einer Bestellung
    struct bestell *aufnehmen(int y, int z)
    {
    	int search=0, anza=0, k;
    	bestellung[y] = malloc(sizeof(struct bestell ));
    
    	printf("Bestell-Nummer: ");
    	scanf("%i", &search);
    
    	printf("Anzahl: ");
    	scanf("%i", &anza);
    
    	for(k=0;k<y;k++)
    	{
    		if(katalog[k]->bestellnummer == search)
    		{
    
    		//bestellung[0]->anz = 2; //selbst das geht nicht
    		bestellung[0]->produkt->bestellnummer = katalog[0]->bestellnummer; // und das erst recht nicht
    
    		}
    
    	else
    		printf("Keine Uebereinstimmung!");
    	}
    
    }
    


  • tommey schrieb:

    struct bestell *aufnehmen(int y, int z)
    {
    	int search=0, anza=0, k;
    	bestellung[y] = malloc(sizeof(struct bestell ));
    
    	printf("Bestell-Nummer: ");
    	scanf("%i", &search);
    
    	printf("Anzahl: ");
    	scanf("%i", &anza);
    
    	for(k=0;k<y;k++)
    	{
    		if(katalog[k]->bestellnummer == search)
    		{
    		
    		//bestellung[0]->anz = 2; //selbst das geht nicht
    		bestellung[0]->produkt->bestellnummer = katalog[0]->bestellnummer; // und das erst recht nicht
    
    		}
    
    	else
    		printf("Keine Uebereinstimmung!");
    	}
    }
    

    - globale Variablen 👎
    - fflush stdin 👎
    - ... 👎
    Wo allokierst du Speicher für bestellung[0] für y!=0?
    Wo weist du bestellung[0]->produkt zu (wenn du davon referenzierst, sollte da auch ein gültiger Speicherbereich liegen)
    ...



  • danke erstmal für deine antwort, ich weiß es sind anfänger fehler aber ich bin anfänger 😉

    Wutz schrieb:

    - globale Variablen 👎

    Könntest du das genauer erläutern, "daumen runter" hilft mir nämlich nicht

    Wutz schrieb:

    - fflush stdin 👎

    ???

    Wutz schrieb:

    - ... 👎

    ???

    Wutz schrieb:

    Wo allokierst du Speicher für bestellung[0] für y!=0?
    Wo weist du bestellung[0]->produkt zu (wenn du davon referenzierst, sollte da auch ein gültiger Speicherbereich liegen)
    ...

    ok Fehler mit der Speichererweiterung erkannt. wenn ich nun anstatt y, 0 eingebe müsste es ja für die erste bestellung ausreichen.
    bestellung[0] = malloc(sizeof(struct bestell ));



  • OK ich hab es jetzt soweit hinbekommen auch mit ausgabe. Ein paar korrekturen feheln noch, wie zB Absturz bei falscher eingabe aber darum kümmere ich mich jetzt.

    Ich würde aber trotzdem gern deine Antwort erläutert bekommen weil ich es gern besser machen will. Ich will dazu lernen und es beim nächsten mal besser machen.
    Es wäre super wenn du nochmal antwortest @ Wutz

    Hier jetzt nochmal der komplette Quellcode

    # include <stdio.h>
    # include <string.h>
    # include <stdlib.h>
    
    // Funktion vom Typ "struct mat", um neue Produkte einzufügen
    struct mat *neumat(int);
    
    // Neue Struktur des Katalogs festlegen
    struct mat {	
    			int bestellnummer; 
    			char produktbezeichnung[20];
    			double preis;
    			}*katalog[20];					// Array mit Platz für 20 Pointer, die auf den Typ struct mat zeigen
    
    // Funktionsprototyp um Bestellung aufzunehmen
    struct bestell *aufnehmen(int, int);
    
    // Neue Struktur der Bestellung festlegen
    struct bestell {
    				int anz;
    				struct mat produkt;
    				double gesamt;
    				}*bestellung[20];			// Array mit Platz für 20 Pointer, die auf den Typ struct bestell zeigen
    
    // Funktion, um Katalog anzuzeigen
    void listeanzeigen(int);
    
    // Funktion, um Bestellung anzuzeigen
    void bestellunganzeigen(int);
    
    int main ()
    {
    	int auswahl=1, i=0, j=0, anzahl=0, anzahl2=0;
    
    	printf("\nHAW Versand AG\n");
    
    	while(auswahl!=0)
    	{
    		printf("\n================================\n");
    		printf("1: neues Produkt eingeben\n");
    		printf("2: Katalog Anzeigen\n");
    		printf("3: Bestellung aufnehmen\n");
    		printf("4: Bestellung anzeigen\n");
    		printf("0: Ende\n");
    		printf("================================\n");
    
    		printf("Auswahl: ");
    
    		fflush(stdin);
    
    		if(scanf("%d", &auswahl)==0)  // Ungültige Eingabe abfangen
    			auswahl=9;
    
    		printf("\n");
    
    		switch(auswahl)
    		{
    			// Ende bei 0
    			case 0:
    				printf("Katalog beendet\n\n");
    				break;
    
    			// Neues Produkt eingeben
    			case 1:
    
    				*neumat(anzahl);
    				anzahl++;
    
    				break;
    
    			// Katalog anzeigen
    			case 2:
    
    				printf("Best-Nr\t%-20s %5s\n", "Bezeichnung", "Preis");
    				printf("----------------------------------\n");
    
    				for(i=0;i<anzahl;i++)
    
    					listeanzeigen(i);
    
    				printf("----------------------------------\n");
    				break;
    
    			// Bestellung aufnehmen
    			case 3:
    
    				*aufnehmen(anzahl, anzahl2);
    				anzahl2++;
    
    				break;
    
    			// Bestellung anzeigen
    			case 4:
    
    				printf("Anz. Best-Nr\t%-20s%6s%7s\n", "Bezeichnung", "E-Preis", "Summe");
    				printf("--------------------------------------------------\n");
    
    				for(j=0;j<anzahl2;j++)
    
    					bestellunganzeigen(j);
    
    				printf("--------------------------------------------------\n");
    				break;
    
    			default:
    
    				printf("Ungueltige Eingabe!\n\n");
    				break;
    
    		}
    	}
    }
    
    // Funktion vom Typ "struct mat", um neue Produkte einzufügen
    struct mat *neumat(int x)
    {
    	// Speicher in Katalog um die Größe von einer "struct mat" erweitern.
    	katalog[x] = malloc(sizeof(struct mat));
    
    	// Speichert die Ganzahl Bestellnummer bei der ersten(usw.) Eingabe an der ersten(usw.) Stelle Bestellnummer im Katalog
    	printf("Bestell-Nummer: "); scanf("%i", &(katalog[x]->bestellnummer));
    
    	printf("Produktbezeichnung: "); scanf("%s", katalog[x]->produktbezeichnung);
    
    	printf("Preis: "); scanf("%lf", &(katalog[x]->preis));
    }
    // Funktion zur Ausgabe des Katalogs
    void listeanzeigen(int n)
    {
    	printf("%7.d", (katalog[n]->bestellnummer));
    	printf("\t%-20s", katalog[n]->produktbezeichnung);
    	printf("%6.2lf\n", (katalog[n]->preis));
    }
    // Funktion zur Aufnahme einer Bestellung
    struct bestell *aufnehmen(int y, int z)
    {
    	int search=0, anza=0, k;
    
    	printf("Bestell-Nummer: ");
    	scanf("%i", &search);
    
    	printf("Anzahl: ");
    	scanf("%i", &anza);
    
    	for(k=0;k<y;k++)
    	{
    		if(katalog[k]->bestellnummer == search)
    		{
    		bestellung[z] = malloc(sizeof(struct bestell ));
    		bestellung[z]->anz = anza;
    		bestellung[z]->produkt.bestellnummer = search;
    		bestellung[z]->produkt.preis = katalog[k]->preis;
    		strcpy(bestellung[z]->produkt.produktbezeichnung,(katalog[k]->produktbezeichnung));
    		bestellung[z]->gesamt = ((katalog[k]->preis)*anza);
    		}
    	}
    }
    
    void bestellunganzeigen(int m)
    {
    	printf("%4.d", (bestellung[m]->anz));
    	printf("%8.d", (bestellung[m]->produkt.bestellnummer));
    	printf("\t%-20s", (bestellung[m]->produkt.produktbezeichnung));
    	printf("%7.2lf", (bestellung[m]->produkt.preis));
    	printf("%7.2lf\n", (bestellung[m]->gesamt));
    }
    


  • - globale Variablen sind ganz schlechtes Design (in wirklich ganz wenigen Fällen nötig)
    - fflush(stdin) ist nicht C standardkonform und führt zu undefiniertem Verhalten
    - ... deutet an, dass o.g. keinen Anspruch auf Vollständigkeit erhebt und somit noch weitere Schlechtigkeiten vorkommen können

    Ein gutes Programm fängt mit gutem Design an, und da hast du gleich mal von

    struct bestell {
                    int anz;
                    struct mat *produkt;
                    double gesamt;
                    }*bestellung[20];            // Array mit Platz für 20 Pointer, die auf den Typ struct bestell zeigen
    

    in

    struct bestell {
                    int anz;
                    struct mat produkt;
                    double gesamt;
                    }*bestellung[20];            // Array mit Platz für 20 Pointer, die auf den Typ struct bestell zeigen
    

    dein Typdesign geändert, was natürlich auch Auswirkungen auf deinen Code hat, denn es ist schon ein Unterschied, ob ich nur eine Referenz oder den kompletten Inhalt speichere.

    Wenn man nicht masochistisch veranlagt ist und ständig "struct" mitschleppen will, wäre z.B. hier angebracht:

    typedef struct {
      int bestellnummer;
      char produktbezeichnung[20];
      double preis;
    } Produkt;
    typedef struct {
      int anz;
      const Produkt *produkt;
      double gesamt;
    } Bestellung;
    

    und dann einfach die Variablendefinition mit

    Produkt *produkt[20];
    Bestellung *bestellung[20];
    

    Deine Funktion aufnehmen ist auch renovierungsbedürtig, z.B. sollte man Benutzereingabe und Datenverarbeitung immer trennen, aber das mach mal selbst; so könnte es gehen:

    int neueBestellungEinfuegen(Produkt **katalog,int kat_groesse,Bestellung **bestellung,int bliste_groesse)
    { /* return >=0 : Suche in katalog erfolgreich, index der neuen bestellung in Bestell-Liste */
      /* <0 : Suche nicht erfolgreich */
      char in[20];
      int search=0, anza=0, k;
    
      printf("Bestell-Nummer: "); fgets( in,20,stdin );
      if( !sscanf(in,"%i", &search) ) return -1;
    
      printf("Anzahl: "); fgets( in,20,stdin );
      if( !sscanf(in,"%i", &anza) ) return -1;
    
      for(k=0;k<kat_groesse;k++)
      {
        if( katalog[k]->bestellnummer == search )
        {
          bestellung[bliste_groesse] = malloc(sizeof(Bestellung));
          bestellung[bliste_groesse]->anz = anza;
          bestellung[bliste_groesse]->produkt = katalog[k]; /* hier mal nachdenken! */
          bestellung[bliste_groesse]->gesamt =  katalog[k]->preis * anza;
          return bliste_groesse;
        }
      }
      return -1;
    }
    

    Aufgerufen bekommst du diese Funktion ja wohl selbst?!
    Zu jedem deiner mallocs gehört auch ein free!

    Ein Lob habe ich aber auch noch:
    Ich habe noch bei keinem (sich selbst als Anfänger bezeichnenden) Fragesteller eine Definition eines Zeigerarrays gesehen.



  • Super Danke, ich werd mich morgen gleich ran machen und versuchen zu ändern,
    vllt find ich ja dazu auch noch was im internet.
    also danke für die hilfe 👍


Anmelden zum Antworten