# Struct,Array, Anfänger braucht hilfe !!



## umx3511 (20. Oktober 2007)

Hallo zusammen ich hoffe mir kann jemand ein wenig helfen, 
wir müssen ein Programm schreiben Teileverwaltung 
die teileliste soll in ein strukturarray deklariert werden ( ID,Bez,Bestand,Preis) 
mit folgenden optionen
1. einlesen
2. ausgeben 
3. Sortieren nach lager ID 
4. löschen nach lager  ID 
5. ändern einzelner Attribute eines teils 

1 und 2 hab ich  aber der rest keine Ahnung 
es währe auch sehr schön wenn sich das Programm die eingegebenen Teile merken könnte und bei einem erneutem aufruf des Programmes ( tag später oder so ) wieder alles da währe 

um denkanstösse währe ich dankbar da mir echt nicht einfällt wie das gehen soll 3-5 und das speichern meiner eingegebenen Teile in z.b einer Datei 

Hier mal mein listing 

```
//---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 


struct teil
{
  char ID[10],bez[40];
  int bestand;
  float preis;
};
// ----------------------------------------------------------------------------
int Anlegen(teil[],int,int);
int Ausgeben(teil[],int,int);
int Sortieren(teil[],int,int);
int Loeschen(teil[],int,int);
int Aendern(teil[],int,int);
void loesche_bild();

// ----------------------------------------------------------------------------


 main()
{
  const int MAX=1000;
  teil lager[MAX];
  char auswahl;
  int anz=0;
  
  do
  {  
    printf("\n %s ",__FILE__); printf("\t\t\t\t\t\t\t %s ",__DATE__);  
     
    printf("\n\n\n\n\n\n\t\t\t\tIhre Auswahl bitte?\n\n\n\n\n\t\t(1) Neues Teil anlegen\n\t\t(2)  
    Alle Teile Anzeigen");
    printf("\n\t\t(3) Sortieren\n\t\t(4) Loeschen \n\t\t(5) Aendern\n\t\t(0) Programm 
    beenden\n");
    printf("\n\n\t\t\    Ihre auswahl bitte : ");
    fflush(stdin);
    scanf("%c",&auswahl);

    switch(auswahl)
    {
      case '1':  anz=Anlegen(lager,anz,MAX);                     break;
      case '2':  loesche_bild();anz=Ausgeben(lager,anz,MAX);     break;
      case '3':  anz=Sortieren(lager,anz,MAX);                   break;
      case '4':  anz=Loeschen(lager,anz,MAX);                    break;
      case '5':  anz=Aendern(lager,anz,MAX);                     break;      
      default:   loesche_bild(); 
                                                              
      
    } 
           
    } 
   while(auswahl != '0');
   printf("\n\n\t\t\t\t Programmende\n\n\n\n");
   system("Pause");
  
}

//------------------------------------------------------------------------------

int Anlegen(teil lager[], int anz,int MAX)
{
  printf("\n\n\tBitte gegen Sie die Teile-ID ein : ");
  fflush(stdin);
  gets(lager[anz].ID);
  printf("\n\n\tBitte gegen Sie die Teile-Bezeichnung ein : ");
  fflush(stdin);
  gets(lager[anz].bez);
  printf("\n\n\tBitte geben Sie den Lagerbestand ein : ");
  fflush(stdin);
  scanf("%i",&(lager[anz].bestand));
  printf("\n\n\tBitte geben Sie den Preis ein : ");
  fflush(stdin);
  scanf("%f",&(lager[anz].preis));
  anz=anz+1;
  loesche_bild();  
  return anz;

  }

//------------------------------------------------------------------------------

int Ausgeben(teil lager[],int anz,int MAX)
{
    int i;
   
    for (i=0;i<anz;i++)
    {
        printf("\n\t\t\t\t Teile ID : %s \n",lager[i].ID);
        printf("\n\tBezeichnung : %s | Lagerbestand : %i | Einkaufspreis : %.2f",
        lager[i].bez,lager[i].bestand,lager[i].preis);
        printf("\n\n\n");
       
    }
     
     system("Pause");
     loesche_bild();
     return anz;   
}    
    
//------------------------------------------------------------------------------

int Sortieren(teil lager[],int anz,int MAX)
{
}

//------------------------------------------------------------------------------

int Loeschen(teil lager[],int anz,int MAX)
{
}

//------------------------------------------------------------------------------

int Aendern(teil lager[],int anz,int MAX)
{
}

//------------------------------------------------------------------------------

void loesche_bild()
{
     int i;
     for (i=0; i<=20;i++)
     {
         printf("\n");
     }
}

//------------------------------------------------------------------------------
```

ich sag schon mal danke !


----------



## sheel (21. Oktober 2007)

Hi umx

Erst einmal ein paar tips:
Beim Ausgeben im printf verwende statt %i besser %d
Beim Array übergeben statt "tel lager[]" besser "teil *lager"
Am main-ende könntest du statt system-Pause auch ohne cmd auskommen:
   "getch();" im conio.h, (vielleich _getch(); bei dir)
Könntest du auch im main bei der auswahl verwenden:
statt "scanf("%c",&auswahl);" "auswahl=getch();"

Und im lösche_bild kannst du den gesamten inhalt(int, for, printf)
durch system("cls"); ersetzen

Dann fang ich gleich mal mit dem Löschen an:

```
int Loeschen(teil lager[],int anz,int MAX)
{
int a;char c[10];
printf("ID?");
gets(c);
//Welches Element soll gelöscht werden?

i=0;
while(strcmp(c,lager[i].ID)&&i<anz) i++;
//Element suchen

if(i==MAX)
{
  printf("Element nicht vorhanden!\n");
  return anz;
}
//Falls zu lösch. teil gar nicht da ist

//Jetzt alle elemente hinter dem eins nach vor schieben, da die "Lücke" gefüllt
//werden muss, die beim Löschen entsteht
//Das eine Element wird dabei automatisch überschrieben
for(i=i;i<(MAX-1);i++)
  lager[i]=lager[i+1];

anz--;//gleich wie anz=anz-1;
return anz;//fertig
}
```


----------



## sheel (21. Oktober 2007)

So erstmal sorry das ich das [code] im ersten beitrag verpatzt hab...
schaut irgendwie unübersichtlich aus.

Mir ist gerade aufgefallen:
Im "Anlegen" sollte eine Kontrolle sein, ob das Array vielleicht schon voll ist, zB
am Anfang von Anlegen:

```
if(anz>=(MAX-1)
{
printf("Es ist bereits alles voll, anlegen nicht moeglich");
return anz;
}
```

Und noch ein kleiner tip:

fflush(stdin); ist NUR nach scanf nötig, nicht nach printf etc!
Wenn du nach dem printf auch ein fflush willst:
fflush(stdout);

Dann erklär ich als nächstes dann einzel-attribut-ändern
schreib aber hier keinen code, wenn du das anlegen geschafft hast
geht es nur noch ums prinzip

Im Ändern musst du als erstes den Benutzer einmal nach der ID von dem Element
fragen, dass er ändern willst.
Wenn du die id bsp-weise im char c[10] eingelesen hast,
suchst du einmal das element wie im löschen:

```
int a;char c[10];
printf("ID?");
gets(c);
//Welches Element

i=0;
while(strcmp(c,lager[i].ID)&&i<anz) i++;
//Element suchen

if(i==MAX)
{
printf("Element nicht vorhanden!\n");
return anz;
}
//Falls zu lösch. teil gar nicht da ist
```

Dann lässt du ihn wie im main in der auswahl einmal wählen, ob er die
id, bezeichnung, bestand oder preis ändern will

Wenn er die ID ändern will: zB

```
printf("Neue ID eingeben: ");
gets(c);//Variable von oben
strcpy(lager[i].ID,c);//Im i von oben ist ja der index von ausgesuchten element
//hier wird also nur die ID durch die neue ersetzt
```
Danach fehlt eigentlich nur noch ein "return anz;" und fertig

Wenn er die Bezeichnung ändern will (am besten alles in ein switch wie in der
main-auswahl) ist es dann halt

```
printf("Neue Bezeichnung eingeben: ");
gets(c);
strcpy(lager[i].bez,c);
```
Bestand:

```
printf("Neuen Bestand eingeben: ");
scanf("%d",&lager[i].bestand);
```
Und der Preis ist dann halt:

```
printf("Neuen Preis eingeben: ");
scanf("%f",&lager[i].preis);
```


----------



## sheel (21. Oktober 2007)

Jetzt kommt das sortieren

Da gibt es schon eine ziemlich schnelle sortierfunktion (ich glaub im "windows.h")
die aber dein lager/teil noch nicht kennt

daher brauchst du eine funktion die zwei teile vergleicht
Du wolltest nach der ID sortieren?

```
int sortfunk(const void *a,const void *b)
{
teil *c;teil *d;
c=(teil *)a;
d=(teil *)b;

//da ID ein string ist kann man ihn nicht mit < oder >
//sonern nur mit strcmp vergleichen
//je nach dem welcher von den zweien größer ist muss 1, -1 oder 0 hintergegeben werden

if(strcmp(c->ID,d->ID)<0)return -1;
//ID 1 ist größer
if(strcmp(c->ID,d->ID)>0)return 1;
//ID 2 ist größer
else return 0;//Beide gleich;
}
```

Duese Funktion mustt du aber selber nicht aufrufen

Wenn jetzt Sortiert werden soll, ruft du die Funktion qsort auf:

qsort(lager,sizeof(teil),anz,sortfunk);
//sorry wenns nicht geht: dann vertausch anz und sizeof(teil),
//bei der reihenfolge bin ich mir nicht ganz sicher

Fertig
!: Falls es beim compiler nicht geht: #include<windows.h>


----------



## sheel (21. Oktober 2007)

Und das Abspeichern:
Mach als erstes nach der der teil-struktur noch was:

union uni
{
struct teil t;
char c[sizeof(teil)];
}

Das ist so was wie eine struktur, wo alle variablen nur andere namen für den gleichen speicherplatz sind.
Mann kann es zB verwenden, um ein teil in einen string zu verwandeln ohne sich ewig mit printf, %d, puts und dergleichen herumärgern.

Hier eine Funktion zum Abspeichern: Ruf sie einfach am ende von main auf:
(Beim Aufruf kein MAX übergeben, sondern nur das lager und anz!)

```
int speich(teil lager[],int anz)
{
uni u;FILE *dat;int i,j;
dat=fopen("Lagerdatei","wb");
if(dat==NULL)
{
printf("Speicherfehler");
return anz;
}

for(i=0;i<anz;i++)
{
 u.t=teil[i];fputc(1,dat);
 for(j=0;j<sizeof(teil);j++)
  fputc(u.c[j],dat);
}

fputc(2,dat);
fclose(dat);
return anz;
}
```

Und zum Laden am main-Anfang:


```
int lade(teil lager[],int anz)
{
uni u;FILE *dat;int i,j;
dat=fopen("Lagerdatei","rb");
if(dat==NULL)
{
printf("Ladefehler");
return anz;
}

anz=0;

while(fgetc(dat)!=2)
{
for(i=0;i<sizeof(teil);i++)
{u.c[i])fgetc(dat);}
lager[anz]=u.t;
anz++;
}

fclose(dat);
return anz;
}
```


----------



## umx3511 (21. Oktober 2007)

Hallo und Danke für die schnelle antwort 
ich werde jetzt mal versuchen das zu verstehen und es dann ausprobieren !!


----------

