PROG 1 – Aufgabe 4 (Notenspiegel)

Ähnlich wie Aufgabe 3 nur hier wird eine verkette Liste benutzt.

Nach der Lösung findet ihr noch eine Lösung für einen Teil der Zusatzaufgaben.

Programmiertechnik 1 – Aufgabe 4 (Notenspiegel)

Lösung:

//
// Aufgabe4.cpp
//
// Programmiertechnik Uebungsaufgabe 4: Notenspiegel mit verketteter Liste
//
// Liest die Namen von Faechern mit den zugehoerigen Noten
// in eine verkettete Liste ein und gibt dann einen Notenspiegel aus.
//
// Autor: Andreas Giemza
// Erstellt am: 24.11.2009
//

#include <iostream>
#include <iomanip>

//=========================================================== Typ-Deklaration
struct FachNote
{
  FachNote *naechsteFachNotePtr;                  // Verkettung
  char fach[40];
  int ganze;
  int zehntel;
};

//============================================================= Hauptprogramm
int main ()
{
  FachNote *ersteFachNotePtr = 0;                 // leere Liste

  //--------------------------------------------------- Notenspiegel einlesen
  std::cerr << "Fach und Note eingeben (Ende mit Strg-d):n";

  for (;;)
  {
    // Speicherplatz reservieren und Note einlesen:
    FachNote *fachNotePtr = new FachNote;
    char komma;

    /* 1: hier die Note in den reservierten Speicherplatz einlesen */

    std::cin >> fachNotePtr->fach >> fachNotePtr->ganze >> komma >> fachNotePtr->zehntel;

    /* 1: Ende */

    // Lesefehler behandeln:
    if (std::cin.fail() || (komma != '.' && komma != ','))
    {
      delete fachNotePtr;

      if (std::cin.eof() || std::cin.bad())
      {
        std::cerr << "Eingabeenden";
        break;
      }

      std::cerr << "Eingabefehlern";
      std::cin.clear();
      char c;
      while (std::cin.get(c) && c != 'n') ;

      continue;
    }

    // neue Fachnote in Notenliste eintragen:

    /* 2: hier Anweisungen schreiben, die die Note am Listenanfang einfuegen */

    fachNotePtr->naechsteFachNotePtr = ersteFachNotePtr;
    ersteFachNotePtr = fachNotePtr;

    /* 2: Ende */
  }

  //--------------------------------------------------- Notenspiegel ausgeben
  std::cout << "nNOTENSPIEGEL:n";

  /* 3: hier eine Schleife schreiben, die alle Noten zeilenweise ausgibt */

  for (FachNote *tempFachNote = ersteFachNotePtr;
    tempFachNote;
    tempFachNote = tempFachNote->naechsteFachNotePtr)
  {
    std::cout << std::setw(40) << std::left;
    std::cout << tempFachNote->fach << " " << tempFachNote->ganze << "," << tempFachNote->zehntel << "n";
  }

  /* 3: Ende */

  //---------------------------------------------------- Notenliste freigeben

  /* 4: hier eine Schleife schreiben, die den Speicher aller Noten freigibt */

  while (ersteFachNotePtr)
  {
    FachNote *tempFachNote = ersteFachNotePtr;
    ersteFachNotePtr = ersteFachNotePtr->naechsteFachNotePtr;
    delete tempFachNote;
  }

  /* 4: Ende */

}                                                 // main

Zusatzaufgaben:

//
// Aufgabe4erweitert.cpp
//
// Programmiertechnik Uebungsaufgabe 4: Notenspiegel mit verketteter Liste
//
// Liest die Namen von Faechern mit den zugehoerigen Noten
// in eine verkettete Liste ein und gibt dann einen Notenspiegel aus.
//
// Autor: Andreas Giemza
// Erstellt am: 30.11.2009
//

#include <iostream>
#include <iomanip>

//=========================================================== Typ-Deklaration
struct FachNote
{
  FachNote *naechsteFachNotePtr;                  // Verkettung
  char fach[40];
  int ganze;
  int zehntel;
};

//============================================================= Hauptprogramm
int main ()
{
  FachNote *ersteFachNotePtr = 0;                 // leere Liste

  //--------------------------------------------------- Notenspiegel einlesen
  std::cerr << "Fach und Note eingeben (Ende mit Strg-d):n";

  for (;;)
  {
    // Speicherplatz reservieren und Note einlesen:
    FachNote *fachNotePtr = new FachNote;
    char komma;

    /* 1: hier die Note in den reservierten Speicherplatz einlesen */

    std::cin >> fachNotePtr->fach >> fachNotePtr->ganze >> komma >> fachNotePtr->zehntel;

    /* 1: Ende */

    // Lesefehler behandeln:
    if (std::cin.fail() || (komma != '.' && komma != ','))
    {
      delete fachNotePtr;

      if (std::cin.eof() || std::cin.bad())
      {
        std::cerr << "Eingabeenden";
        break;
      }

      std::cerr << "Eingabefehlern";
      std::cin.clear();
      char c;
      while (std::cin.get(c) && c != 'n') ;

      continue;
    }

    // neue Fachnote in Notenliste eintragen:

    /* 2: hier Anweisungen schreiben, die die Note am Listenanfang einfuegen */

    // Zeigt auf das vorherige Element, am Anfang wird es auf Null gesetzt
    FachNote *laufPtr = 0;
    // Zeiger auf das Element das geprueft wird, wird vor der for-Schleife initialisiert da wir es auch ausserhalb brauchen
    FachNote *lauf2Ptr;

    // Normale for-Schleife wird lauf2 am Anfang auf ersteFachNotePtr gesetzt und immer zum naechsten erhoeht, AUSSER ersteFachNotePtr ist noch leer oder
    // die neue Note (fachNotePtr) ist kleiner als die erste in der Liste
    for (lauf2Ptr = ersteFachNotePtr;
      lauf2Ptr != 0 && (fachNotePtr->ganze > lauf2Ptr->ganze || (fachNotePtr->ganze >= lauf2Ptr->ganze && fachNotePtr->zehntel > lauf2Ptr->zehntel));
      lauf2Ptr = lauf2Ptr->naechsteFachNotePtr)
    {
      // Setzt laufPtr auf das aktuelle Elment, also wenn die Schleife abgebrochen wird zeigt laufPtr auf das vorherige von lauf2Ptr
      laufPtr = lauf2Ptr;
    }

    // Da laufPtr noch 0 ist, wurde die for-Schleife uebersprungen da es das erste Element ist oder das kleineste udn es muss an den Anfang gehaengt werden
    if (laufPtr == 0)
      // ersteFachNotePtr zeigt auf das neue erste Element
      ersteFachNotePtr = fachNotePtr;
    else
      // Das vorherige Elment das wir ja in laufPtr haben lassen wir auf das neue Zeigen
      laufPtr->naechsteFachNotePtr = fachNotePtr;

    // Das neue Elment muss auf das naechste Element das wir ja in laufPtr haben
    fachNotePtr->naechsteFachNotePtr = lauf2Ptr;

    /* 2: Ende */
  }

  //--------------------------------------------------- Notenspiegel ausgeben
  std::cout << "nNOTENSPIEGEL:n";

  /* 3: hier eine Schleife schreiben, die alle Noten zeilenweise ausgibt */

  for (FachNote *tempFachNote = ersteFachNotePtr;
    tempFachNote != 0;
    tempFachNote = tempFachNote->naechsteFachNotePtr)
  {
    std::cout << std::setw(40) << std::left;
    std::cout << tempFachNote->fach << " " << tempFachNote->ganze << "," << tempFachNote->zehntel << "n";
  }

  /* 3: Ende */

  //---------------------------------------------------- Notenliste freigeben

  /* 4: hier eine Schleife schreiben, die den Speicher aller Noten freigibt */

  while (ersteFachNotePtr != 0)
  {
    FachNote *tempFachNote = ersteFachNotePtr;
    ersteFachNotePtr = ersteFachNotePtr->naechsteFachNotePtr;
    delete tempFachNote;
  }

  /* 4: Ende */

}                                                 // main
This entry was posted in Programmiertechnik 1 and tagged . Bookmark the permalink.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>