Hilfe bei Strukturzuweisungen



  • Hallo,
    ich bin noch recht neu bei C und muss für die FH eine Hausübung machen. Konnte auch drei von vier Aufgaben mit ein wenig tüfteln rauskriegen. Komme jetzt aber berhaupt nicht mehr weiter! Habe auch schon mind. 5 Stunden mein Glück versucht, aber komme nicht weiter und wende mich jetzt an euch.
    Uns wurden eine Header und eine C Datei vorgegeben aus der wir dann die Lösung bauen sollen.

    Ich habe mit Aufgabe 3. ein Problem und hoffe den Rest soweit richtig zu haben.
    Hier ein Link zur ganzen Aufgabenstellung.
    http://homepages.thm.de/christ/Start/01Lehre/07KSP/aktuell/Uebung/KSPU02.pdf
    Hier mal das, worums bei mir geht:
    Zur Vervollständigung der Funktion (Markierung MORE_STRUCT3) fehlt noch die Speicherplatz-Reservierung und die Zuweisung der Leistungsdaten. Die drei benötigten Leistungen sollen den Studierenden aus der Reihe der gespeicherten Vorlesungen so zugeordnet werden, daß Matr. 1 die Vorlesungen mit den Indizes 0-2 hat, Matr. 2 jene mit Indizes 1-3 etc.. Bei Erreichen der letzten Vorlesung wird die Zuordnung zyklisch wiederholt.
    Als Note wird schließlich für jedes Fach eine zwischen 2 und 3 zufällig gewählte Note mit einem ebenfalls zufällig gebildeten Versatz, der 0 oder ±0,3 betragen kann.

    Konkret weiß ich nicht, wie ich auf die Daten zugreifen kann bzw wie ich das zuweise. Die Strukturen sollen nicht verändert werden und ich habe keinen Schimmer wie ich es hinbekommen kann

    Die Struktur:

    typedef struct
     { struct Fach;
       float  FachNote;
     } Leistg;
    

    aber wie soll ich auf FachName aus Fach/Vorlesung zugreifen!?

    Zugriff auf 'FachName' von fast ganz unten Zeile 119:

    BS_S[j1].Leist[j2].FachName, BS_S[j1].Leist[j2].FachNote);     }
    

    Ob die

    /* strucTest.c */
    /*Zeiger und Strukturen am Bsp. einer "MNI-Datenbank"*/
    #include "strucTest.h"
    
    /* *********************************************************************** */
       char *namXpath (char *namPath)
    /* *********************************************************************** */
    { /*Extraktion des Programmnamens aus dem uebergebenen Pfad:*/
    
    	char *shortPath = strrchr(namPath, '\\')+1; //Aufgabe 1 anstatt '\\' auch Übergabe der Konstanten BSLS mit dem ASCII Wert möglich
    	namPath=NULL;
    	namPath= shortPath;							//Aufgabe 1
    
      return namPath; 
    }
    
    /* *********************************************************************** */
       int randRang(int rangeMin, int rangeMax)
    /* *********************************************************************** */
    { /*Pseudo-Zufallszahlen innerhalb eines Zahlenintervalls (range):*/
      int randR=0;
      randR = rangeMin + ( rand() % (rangeMax-rangeMin+1 )); //Aufgabe 2
      return (randR);
    }
    
    /* *********************************************************************** */
       int setStud (Stud *defSt, Vorlesg *BS_V)
    /* *********************************************************************** */
    { static int LfdNr=1;
             int j1=0;
    
      sprintf (defSt->Name, "%c.%c.", randRang('A','Z'), CYCLIC(LfdNr,'A','Z'));										
    
      defSt->Matrikel = LfdNr;
      defSt->nLeist = 3;																								
    
       defSt->Leist = (Leistg *)calloc (3, sizeof(Leistg)); //Speicherallokation; -> Pfeiloperator weißt			
    
    //HIERUM GEHT ES  
       defSt->Leist->Fach->FachName =BS_V->FachName;
    
    	  defSt->Leist->FachNote=4;  //zum Testen alle Noten=4
    //HIERUM GEHT ES 
    
     LfdNr++;
      return OK;
    }
    
    /* *********************************************************************** */
       int main(int argc, char *argv[]) 
    /* *********************************************************************** */
    { Prof    BS_P[PROF];
      Stud    BS_S[STUD];
      Vorlesg BS_V[VORL];
      int     j1=5, j2=8; // Mit (-2)...(3) probieren!
    
    #ifdef  _DEBUG // _entfernen für VS2010!!
      /*Groesse beteiligter Strukturen:*/
      printf (" sizeof(struct Fach)= %d\n\r", sizeof(struct Fach));
      printf (" sizeof(Vorlesg)    = %d\n\r", sizeof(Vorlesg));
      printf (" sizeof(Prof)       = %d\n\r", sizeof(Prof));
      printf (" sizeof(Leistg)     = %d\n\r", sizeof(Leistg));
      printf (" sizeof(Stud)       = %d\n\r", sizeof(Stud));
      /*Zufallszahlen-Test, bis ESC gedrueckt wird:*/
      printf ("\n\r Pseudo-Zufallszahlen zwischen %d und %d:", j1, j2);
      printf ("\n\r (Bel. Taste / Weiter mit Esc)\n\r");
      while (_getch() != ESC) { printf("%6d\n", randRang(j1,j2)); } system("cls");
    #else //DEBUG
      /*Initialisierung der Zufallszahlen fuer diesen Start:*/
      srand((unsigned)time(NULL));
    #endif//DEBUG
    
      /*Eigentlicher Programmstart:*/
      printf (" Sie haben das Programm \"%s\" gestartet\n\n\r", namXpath(argv[0]));
    
      /*Angebotene Vorlesungen:*/
      strcpy (BS_V[0].FachName, "KonzSysProg"); BS_V[0].FachSWS = 4;
      strcpy (BS_V[1].FachName, "Comp.Grafik"); BS_V[1].FachSWS = 3;
      strcpy (BS_V[2].FachName, "BildVerarb."); BS_V[2].FachSWS = 2;
      strcpy (BS_V[3].FachName, "MathematikI"); BS_V[3].FachSWS = 6;
      strcpy (BS_V[4].FachName, "Th.Physik I"); BS_V[4].FachSWS = 3;
    
      /*Professoren:*/
      for (j1=0; j1<PROF; j1++)
      { sprintf (BS_P[j1].Name, "%c.%c.", CYCLIC(j1+1,'A','Z'), CYCLIC(j1+1,'C','Z'));
        BS_P[j1].nVorl=3;
        BS_P[j1].Vorl = (Vorlesg *)calloc (BS_P[j1].nVorl, sizeof(Vorlesg));
        if (!BS_P[j1].Vorl) { printf("Kein Speicher fuer Prof[%d]!\n", j1); _getch(); exit(1); }
        printf (" Prof. %s liest z.Z.:\n\r", BS_P[j1].Name);
        for (j2=0; j2<BS_P[j1].nVorl; j2++)
        { BS_P[j1].Vorl[j2] = BS_V[(j1+j2)%VORL]; //Strukturzuweisung
          printf (" %s (%d SWS)\n\r", 
                  BS_P[j1].Vorl[j2].FachName, BS_P[j1].Vorl[j2].FachSWS );
        } printf ("\n\r");
      }
    
      /*Stichprobe als Plausibilitaetskontrolle:*/
        printf (" Speicheradressen:\n\r");
        printf (" BS_P[0].Vorl[1]:%8d\n\r", &BS_P[0].Vorl[1]);
        printf (" BS_P[0].Vorl[0]:%8d\n\r", &BS_P[0].Vorl[0]);
    
    	j1 = sizeof(BS_P[0].Vorl[0]); //Aufgabe 4 FUNKTIONIERT
    
        printf (" Differenz:      %8d\n\n\r", j1);
        if (j1 != sizeof(Vorlesg)) printf(" Codierungsfehler!\n\n\r"); _getch(); 
    
      /*Studierende:*/
      for (j1=0; j1<STUD; j1++)
      { if (!setStud (&BS_S[j1], BS_V)) { printf ("Fehler!"); _getch(); exit(0); }
        printf (" Herr/Frau %s (Matr. %d) bekam: \n\r", BS_S[j1].Name, BS_S[j1].Matrikel);
        for (j2=0; j2<BS_S[j1].nLeist; j2++)
        {  printf ("\tin %s die Note \"%3.1f\"\n\r", 
    
    //HIERUM GEHT ES - das ist vorgegeben
    	BS_S[j1].Leist[j2].FachName, BS_S[j1].Leist[j2].FachNote);     }  printf ("\n\r");
    
    //HIERUM GEHT ES - das ist vorgegeben
      }
    
      printf ("\n\r Ende!\n\r(bel. Taste)");  _getch();
      return 1;
    }
    

    und nun die Header Datei

    /* strucTest.h */
    #ifndef STRUCTEST_H
     #define STRUCTEST_H
    
     #pragma warning(disable : 4996) // ("veraltet" nicht mehr melden!)
    
     #include <conio.h>  // _getch()
     #include <stdio.h>  // printf()
     #include <stdlib.h> // calloc()
     #include <string.h> // strcpy()
     #include <time.h>   // time()
    
     //#define DEBUG
     //#define MORE_STRUCT1
     //#define MORE_STRUCT2
     //#define MORE_STRUCT3
     //#define MORE_STRUCT4
    
     /*Benoetigte Konstanten:*/
     #define ESC    27
     #define LANG   20
     #define OK      1
     #define PROF    3
     #define STUD    5
     #define VORL    5
    
     /*Typische Begrenzungszeichen in Pfad-Angaben:*/
     #define SLSH   47 // ASCII ("/")
     #define BSLS   92 // ASCII ("\")
    
     /*Zyklisches Zaehlen zwischen willkuerlichen Grenzen A und Z (A<Z, Nr=1,...):*/
     #define CYCLIC(Nr,A,Z) (((Nr)+(Z)-(A)) % ((Z)-(A)+1) + (A)) //CYCLIC(24,1,12)=12, CYCLIC(0,1,2)=2
    
     /*Daten-Strukturen und -Typen:*/
     typedef struct Fach
     { char FachName[LANG]; //Studiengang, ...
       int  FachSWS;        //Praktikum, CreditPoints, ...
     } Vorlesg;
    
     typedef struct 
     { char     Name[LANG]; //Vorname, Familienname, Geburtsname, ...
       int      nVorl;      //PersoNr., Dienstalter, Geburtsjahr, ...
       Vorlesg *Vorl;
     } Prof;
    
     typedef struct
     { struct Fach;
       float  FachNote;
     } Leistg;
    
     typedef struct 
     { char     Name[LANG]; //Vorname, Familienname, Heimat-Adresse, ...
       int     Matrikel;    //Studienbeginn, ...
       int     nLeist;
       Leistg *Leist;
     } Stud;
    
     #endif//STRUCTEST_H
    

    Viel zu lesen, ich weiß, aber wäre super, wenn mir jemand helfen könnte! :xmas1:



  • Gude, sitze bei dir im Kurs. Nur das ich das Vergnügen hatte vorher schon mal ein Semester lang ne anständige C-Vorlesung hören durfte. Kann dich schon verstehen wenn du da etwas Probleme hast.

    Ich hab die Aufgabe schon fertig und auch korrekt abgegeben. Meine setStud sieht so aus:

    int setStud (Stud *defSt, Vorlesg *BS_V)
    { 
    	static int LfdNr=1;
    	int j1=0,k;
    	static int counter=0;	
    
    	sprintf (defSt->Name, "%c.%c.", randRang('A','Z'), CYCLIC(LfdNr,'A','Z'));
    
    	defSt->Matrikel = LfdNr;
    	defSt->nLeist = 3;
    
    		defSt->Leist =(Leistg *)calloc(3,sizeof(Leistg));
    
    		if (counter == 5)
    			counter = 0;
    		k = counter;
    
    		for(j1=0; j1 < 3 ; j1++)
    		{
    			if (k==5)
    				k=0;
    
    			strcpy(defSt->Leist[j1].FachName,BS_V[k].FachName);		
    			defSt->Leist[j1].FachSWS = BS_V[k++].FachSWS;
    
    			defSt->Leist[j1].FachNote = randRang(2,3) + randRang(-1,1)/3.0;
    		}
    		counter++;
    
    	#ifdef  MORE_STRUCT3
    	#endif//MORE_STRUCT3
    
    	LfdNr++;
    
    	return OK;
    }
    

    Ich weis jetzt nicht genau wo dein Problem liegt, meinst du etwa das dir die IDE einen Fehler ausgibt:
    "class "Leistg"" hat keinen Member ""FachSWS"". ?
    Wenn ja kannst du das ignorieren, wenn dus Compilierst klappt alles wunderbar.

    Hatte auch eine heiden Diskussion darüber weil das einfach meiner Ansicht nach totaler unübersichtlicher humbug ist den keiner mehr überblickt.

    Das kommt daher, dass defSt ein Pointer auf ein typedef struct Stud ist.
    Die struktur ist hier anonym und besitzt keinen Bezeichner sondern nur eine typedefinition Stud.

    Innerhalb dieser struktur der typ definition von Stud ist wiederum ein Pointer auf eine anonyme struktur mit einer typ definition Leistg.

    So und jetzt kommt der clou da in der anonymen struktur mit der typedefinition Leistg drin steht:

    typedef struct
     { 
       struct Fach;
       float  FachNote;
     } Leistg;]
    

    Ist das wie als würdest du z.B. nur int schreiben, da das struct und fach zusammengehören.

    Dadurch wird zur Compilierzeit der Inhalt der Struktur hineinkopiert. Das würde nach der Compilierung dann so aussehen:

    typedef struct
     { 
       char FachName[LANG]; //Studiengang, ...
       int  FachSWS;        //Praktikum, CreditPoints, ...
       float  FachNote;
     } Leistg;
    

    Das ist meiner Ansicht nach aber totaler Käse so etwas zu Programmieren, da dies meiner Ansicht nach einer erhebliche Verschlechterung der Code Lesbarkeit darstellt.

    Würdest du z.B. der Struktur einen Bezeichner spendieren, würde der Fehler ignoriert:

    [code="c"] typedef struct
     { 
       struct Fach f;
       float  FachNote;
     } Leistg;]
    

    [/code]

    Du könntest jetzt über:

    defSt->Leist[j1].f.FachName
    

    normal auf die Struktur zugreifen mit der IntelliSense.

    Das Problem hierbei ist halt das die IntelliSense keinen Member zum Bearbeitungszeitpunkt sehen kann da dieser erst bei der Compilierung eingefügt wird.

    Hab dir hier mal mein src geuploadet: http://ul.to/ixje8oly falls ich dein Fehler missverstanden habe.

    Viele Grüße
    Vertax und bis morgen 😉



  • Hallo!

    Ich hab ein Problem bei der erzeugung der Zufallszahlen.

    1. Ich bin mir nicht sicher ob ich die Zahlen richtig generiere.

    2. Ich weiß nicht wie man, dass problem mit dem +/- 0,3 versatz realisieren soll.

    ...

    @ Vertax
    Du hast die erste Übung hochgeladen .. meinste du kannst Übung 2 hochladen?
    oder den code für das genergieren bzw setStud posten?
    Daaaanke! 🙂



  • 2. Ich weiß nicht wie man, dass problem mit dem +/- 0,3 versatz realisieren soll.

    Einfach so:
    [/code]defSt->Leist[j1].FachNote = randRang(2,3) + randRang(-1,1)/3.0;

    Sorry, war gestern bissle spät  :p 
    Hier die UE2: http://ul.to/fehqdhzp
    
    Die Zufallszahlen generiere ich so:
    
    [code="c"]/*Pseudo-Zufallszahlen innerhalb eines Zahlenintervalls (range):*/
    int randRang(int rangeMin, int rangeMax)
    { 
    	int randR=0;
    #ifdef  MORE_STRUCT2
    #else //MORE_STRUCT2
    
    	 //Modulo operation liefert maximal einen Rest zwischen 0 und rangeMax+1
    	 //Da am Schluss + rangeMin addiert wird um bei einem Rest von 0 den minimal Wert zu generieren
    	 //muss dies vorher abgezogen werden, da man ansonsten über rangeMax liegt.
    	 randR = rand() % ((rangeMax+1) - rangeMin) + rangeMin;
    
    	 /*Version MSDN-Onlinehilfe (angepasst):*/
    
         // randR = (int)(((double) rand() / RAND_MAX) * rangeMax + rangeMin);
    
    #endif//MORE_STRUCT2
    
      return (randR);
    }
    


  • ahhh - vielen dank! 🙂
    hatte das rand() auch so, nur war ich mir nicht sicher ob die zahlen so gleichverteilt sind.

    bist ein schatz 😃



  • Ist ja sehr lustig das sich hier gleich mehrere aus dem Kurs tummeln.
    Das spricht nicht für unseren Prof 🙄

    Wie kann der Kerl denn auf die Idee kommen das mit struct so zu machen.. Wenn man noch neu ist und sowas nicht kennt - und in KEINEM Lehrbuch war auch nur annähernd so ein Beispiel - wie soll man das denn hinbekommen?

    Hat mich insgesamt bestimmt zehn Stunden meines Lebens gekostet 😡

    Naja, zumindest vergessen werde ich es so schnell sicher nicht mehr 😃

    Um so größer natürlich der Dank an Vertax 👍

    Wenn bei der dritten HÜ Probleme auftauchen kann man hier denke ich auch nochmal reden!? Oder eMails austauschen?!

    In Betriebssysteme hockt nicht zufällig auch noch jemand? 🕶
    Das wird nämlich die nächste Herausforderung.

    Also nochmal, vielen vielen Dank!

    Grüße
    Hunter



  • Hallo Leute,

    ich hoff ihr seit noch dabei und schaut hier noch rein 😃

    bin bei aufgabe 4 und hab keine ahnung wie ich vorgehen soll!

    1. Darf man seinen Code nur in KSP.h und KSP.c einfügen?

    2. Wieso braucht man einen Callback mit redisplay?

    3. Wie bekommt man hin, dass durch drücken von s und d sich die zeilen verschieben?

    Vielen Dank 😉


Anmelden zum Antworten