Sitzung: Jeden Freitag in der Vorlesungszeit ab 16 Uhr c. t. im MAR 0.005. In der vorlesungsfreien Zeit unregelmäßig (Jemensch da?). Macht mit!

C-Kurs/Sammelbestellung: Unterschied zwischen den Versionen

K (Teil 1)
K (verschob „Ckurs/Sammelbestellung“ nach „C-Kurs/Sammelbestellung“)
 
(13 dazwischenliegende Versionen von 5 Benutzern werden nicht angezeigt)
Zeile 4: Zeile 4:
 
Lest Euch die Aufgabe zunächst komplett durch und überlegt, welche Datenstrukturen ihr aufbauen müsst. Macht euch auf einem Blatt Papier einen Plan, welche Funktionalitäten ihr in Funktionen ausgliedern wollt, z.B. Datensatz einfügen, suchen, entfernen, Liste ausgeben, Datei einlesen, etc. damit ihr diese Funktionen in den späteren Aufgaben einfach wieder verwenden könnt.  
 
Lest Euch die Aufgabe zunächst komplett durch und überlegt, welche Datenstrukturen ihr aufbauen müsst. Macht euch auf einem Blatt Papier einen Plan, welche Funktionalitäten ihr in Funktionen ausgliedern wollt, z.B. Datensatz einfügen, suchen, entfernen, Liste ausgeben, Datei einlesen, etc. damit ihr diese Funktionen in den späteren Aufgaben einfach wieder verwenden könnt.  
  
Die einzelnen Teilaufgaben bauen aufeinander auf und sollten daher in dieser Reihenfolge bearbeitet werden. Bearbeitet jede Tailaufgabe am besten in einem eigenen Unterverzeichnis, so dass ihr am Ende für jede Teilaufgabe eine einzelne Datei mit dem Quellcode habt.
+
Die einzelnen Teilaufgaben bauen aufeinander auf und sollten daher in dieser Reihenfolge bearbeitet werden. Bearbeitet jede Teilaufgabe am besten in einem eigenen Unterverzeichnis, so dass ihr am Ende für jede Teilaufgabe eine einzelne Datei mit dem Quellcode habt.
  
  
Zeile 10: Zeile 10:
  
 
Eine Gruppe möchte zum Zweck des Sparens von Versandkosten gemeinsam bei einem Onlinehändler bestellen. Dabei soll von allen Bestellern
 
Eine Gruppe möchte zum Zweck des Sparens von Versandkosten gemeinsam bei einem Onlinehändler bestellen. Dabei soll von allen Bestellern
eine Bestellliste im CSV-Format entgegengenommen werden. Diese Einzellisten sollen dann zu einer Gesamtbestelliste zusammengeführt werden, die für jeden Artikel auflistet, wie oft er bestellt wurde. Bestellen mehrere Personen denselben Artikel, so soll dies anhand der Bestellnummer erkannt werden und dieser auf der Gesamtliste natürlich nur einmal, aber mit passender Menge, erscheinen.
+
eine Bestellliste im CSV-Format entgegengenommen werden. Diese Einzellisten sollen dann zu einer Gesamtbestellliste zusammengeführt werden, die für jeden Artikel auflistet, wie oft er bestellt wurde. Bestellen mehrere Personen denselben Artikel, so soll dies anhand der Bestellnummer erkannt werden und dieser auf der Gesamtliste natürlich nur einmal, aber mit passender Menge, erscheinen.
  
Neben dieser Bestelliste soll am Ende eine kurze Liste ausgegeben werden, die angibt wieviele Produkte jeder einzelne Teilnehmer bestellt hat und wieviel Geld er bezahlen muß. Vereinfachung: Die Versandkosten sollen anhand der Menge der Artikel aufgeteilt werden, nicht nach dem Gewicht.
+
Neben dieser Bestellliste soll am Ende eine kurze Liste ausgegeben werden, die angibt wie viele Produkte jeder einzelne Teilnehmer bestellt hat und wie viel Geld er bezahlen muss. Vereinfachung: Die Versandkosten sollen anhand der Menge der Artikel aufgeteilt werden, nicht nach dem Gewicht.
  
Im Vorfeld ist nicht bekannt, wieviele Personen insgesamt bestellen.
+
Im Vorfeld ist nicht bekannt, wie viele Personen insgesamt bestellen.
  
<!-- TODO: Beachtet die Vorgaben zu dieser Aufgabe, welche ihr hier herunterladen könnt: ..... (csv-dateien, programmrümpfe?) -->
+
<b>Beachtet bitte die Vorgaben zu dieser Aufgabe</b>, welche ihr hier herunterladen könnt: [http://docs.freitagsrunde.org/Veranstaltungen/ckurs_2009/vorgaben/Sammelbestellung_Vorgaben.tgz]. (Entpacken mit <tt>tar -xzf Sammelbestellung_Vorgaben.tgz</tt> (unter Solaris <tt>gtar ...</tt>) oder [http://docs.freitagsrunde.org/Veranstaltungen/ckurs_2009/vorgaben/Sammelbestellung/ einzeln runterladen])
  
 
=== Teil 1 ===
 
=== Teil 1 ===
 +
<!-- meine Bearbeitungszeit: 20 Minuten -->
  
 
Erweitere die untenstehende Vorgabe so, dass jeder Aufruf der <tt>addItem()</tt>-Funktion den Artikel in einer einfach verketteten Liste speichert.
 
Erweitere die untenstehende Vorgabe so, dass jeder Aufruf der <tt>addItem()</tt>-Funktion den Artikel in einer einfach verketteten Liste speichert.
  
Diese Liste soll am Ende des Programms auf dem Bildschirm formatiert ausgegeben werden, nachdem alle Artikel in der Liste gespeichert sind.
+
Diese Liste soll am Ende des Programms auf dem Bildschirm formatiert ausgegeben werden, nachdem alle Artikel in der Liste gespeichert sind. Dabei spielt die Reihenfolge der Ausgabe keine Rolle, es kann also sowohl an den Anfang wie an das Ende der Liste angehangen werden.
  
 
Dazu musst Du zunächst die struct-Definition der Listenelemente sinnvoll festlegen und einige Hilfsfunktionen zum Einfügen in die Liste und Ausgeben der Liste am Ende programmieren:
 
Dazu musst Du zunächst die struct-Definition der Listenelemente sinnvoll festlegen und einige Hilfsfunktionen zum Einfügen in die Liste und Ausgeben der Liste am Ende programmieren:
  
  typedef struct litem_t{
+
<pre>
  ...
+
#include <stdlib.h>
  } litem;
+
 
 
+
typedef struct litem_t
  typedef struct llist_t{
+
{
  struct litem_t *item;
+
// ...
  struct llist_t *next;
+
} litem;
  } llist;
+
 
 
+
typedef struct llist_t
  llist* addItem(llist* alist, char* orderno, char* name, float price, int count, float sum){
+
{
  ...
+
struct litem_t *item;
  }
+
struct llist_t *next;
 
+
} llist;
  ...weitere Hilfsfunktionen ...
+
 
 
+
llist* addItem(llist* alist, char* orderno, char* name, float price, int count, float sum)
  int main(int argc, char** argv){
+
{
  ...
+
// ...
  llist *alist;  
+
}
  alist= addItem(NULL, "UT 2042 C","40 MHz-Digital-Speicher-Oszilloskop",349.00, 1, 349.00);
+
 
  alist= addItem(alist, "AGF 2 SW","Hirschmann-Abgreifklemme 4mm schwarz",5.10,1, 5.10);
+
// weitere Hilfsfunktionen ...
  ...
+
 
  /* ausgeben der Liste: */
+
int main(int argc, char** argv)
  ...
+
{
  }
+
// ...
 +
 +
llist *alist;  
 +
alist= addItem(NULL, "UT 2042 C","40 MHz-Digital-Speicher-Oszilloskop",349.00, 1, 349.00);
 +
alist= addItem(alist, "AGF 2 SW","Hirschmann-Abgreifklemme 4mm schwarz",5.10,1, 5.10);
 +
 +
// ...
 +
 +
/* ausgeben der Liste: */
 +
// ...
 +
 +
}
 +
</pre>
  
  
Zeile 59: Zeile 72:
 
=== Teil 2 ===
 
=== Teil 2 ===
  
Schreibe ein Programm, dass eine csv-Datei 'bestellung.csv' aus dem aktuellen Verzeichnis einliest und auf dem Bildschirm
+
Schreibe ein Programm, dass eine CSV-Datei 'bestellung.csv' aus dem aktuellen Verzeichnis einliest und auf dem Bildschirm ausgibt, wie viele Artikel bestellt wurden und was diese insgesamt kosten. Das Einlesen der Datei befindet sich bereits ausprogrammiert in der Vorgabe.
ausgibt, wieviele Artikel bestellt wurden und was diese insgesamt kosten.
 
  
Die Artikel sollen dazu zunächst in einer einfach verketteten Liste unsortiert gespeichert werden, danach soll diese
+
Die Artikel sollen dazu zunächst in einer einfach verketteten Liste unsortiert gespeichert werden, danach soll diese Liste vom Anfang durchlaufen werden und die Artikel gezählt sowie der Preis berechnet werden.
Liste vom Anfang durchlaufen werden und die Artikel gezählt sowie der Preis berechnet werden.
 
  
 
Die CSV-Datei hat folgendes Format (Beispiele in den Vorgaben):
 
Die CSV-Datei hat folgendes Format (Beispiele in den Vorgaben):
  
 
  Bestellnummer, Kurzbeschreibung, Einzelpreis, Anzahl, Preis
 
  Bestellnummer, Kurzbeschreibung, Einzelpreis, Anzahl, Preis
  UT 2042 C, 40 MHz-Digital-Speicher-Oszilloskop 349.00, 1, 349.00  
+
  UT 2042 C, 40 MHz-Digital-Speicher-Oszilloskop, 349.00, 1, 349.00  
  AGF 2 SW, Hirschmann-Abgreifklemme 4mm schwarz 5.10,1, 5.10
+
  AGF 2 SW, Hirschmann-Abgreifklemme 4mm schwarz, 5.10,1, 5.10
  AK 2 RT, Hirschmann-Krokoklemme 4mm rot 1.80, 1, 1.80
+
  AK 2 RT, Hirschmann-Krokoklemme 4mm rot, 1.80, 1, 1.80
  
 
=== Teil 3 ===
 
=== Teil 3 ===
  
Stelle nun sicher, dass ein Artikel immer nur einmal in die Liste aufgenommen werden kann. Ist er bereits in der Liste
+
Stelle nun sicher, dass ein Artikel immer nur einmal in die Liste aufgenommen werden kann. Ist er bereits in der Liste vorhanden, so soll die Anzahl und der Preis angepasst werden. Stelle außerdem sicher, dass beim Einlesen der Liste der Preis jeweils das Produkt aus Anzahl und Einzelpreis ist, und sich keine Fehler in der Bestellliste eingeschlichen haben.
vorhanden, so soll die Anzahl und der Preis angepasst werden. Stelle ausserdem sicher, dass beim Einlesen der Liste der Preis jeweils das Produkt aus Anzahl und Einzelpreis ist, und sich keine Fehler in der Bestellliste eingeschlichen haben.
 
  
 
Erweitere nun das Programm so, dass der Dateiname auf der Kommandozeile angegeben werden kann und so nacheinander mehrere Teilbestellungen bearbeitet werden können.
 
Erweitere nun das Programm so, dass der Dateiname auf der Kommandozeile angegeben werden kann und so nacheinander mehrere Teilbestellungen bearbeitet werden können.
Zeile 81: Zeile 91:
 
=== Teil 4 ===
 
=== Teil 4 ===
  
Das Programm soll nun beliebig viele Dateinamen als Kommandozeilenparameter beim Start übergeben bekommen und für jeden einzelnen eine neue
+
Das Programm soll nun beliebig viele Dateinamen als Kommandozeilenparameter beim Start übergeben bekommen und für jeden einzelnen eine neue Liste führen. Am Ende soll dann in einem Block eine kurze, formatierte Tabelle ausgegeben werden, welche eine Spalte mit dem Dateinamen, dann die Anzahl der Produkte und den Endpreis aus der Bestellung enthält:
Liste führen. Am Ende soll dann in einem Block eine kurze, formatierte Tabelle ausgegeben werden, welche eine Spalte mit dem Dateinamen, dann die Anzahl der Produkte und den Endpreis aus der Bestellung enthält:
 
  
 
  Dateiname      Produkte  Gesamtpreis
 
  Dateiname      Produkte  Gesamtpreis
Zeile 95: Zeile 104:
 
=== Teil 5 ===
 
=== Teil 5 ===
  
Erweitere das Programm jetzt schließlich so, dass nach dem kompletten einlesen der einzelnen Listen die Gesamtbestelliste in eine Datei geschrieben wird. Dazu muss zunächst noch eine verkettete Liste angelegt werden, welche die Gesamtbestellung enthält.
+
Erweitere das Programm jetzt schließlich so, dass nach dem kompletten Einlesen der einzelnen Listen die Gesamtbestellliste in eine Datei geschrieben wird. Dazu muss zunächst noch eine verkettete Liste angelegt werden, welche die Gesamtbestellung enthält.
  
 
Am Ende soll dann die Tabelle aus Teil 3 auf dem Bildschirm ausgeben werden und eine Datei 'gesamt.csv' im aktuellen Verzeichnis angelegt werden, welche die Gesamtbestellung enthält. Das Dateiformat ist hier exakt wie bei den einzelnen Bestelllisten.
 
Am Ende soll dann die Tabelle aus Teil 3 auf dem Bildschirm ausgeben werden und eine Datei 'gesamt.csv' im aktuellen Verzeichnis angelegt werden, welche die Gesamtbestellung enthält. Das Dateiformat ist hier exakt wie bei den einzelnen Bestelllisten.
 +
 +
=== Zusatzaufgabe ===
 +
 +
Sorge dafür, dass vor dem Beenden des Programms aller Speicher der Liste freigegeben wird. Was ist dabei zu beachten?
 +
 +
== Lösung ==
 +
Eine Teilimplementierung ist [[Ckurs2009/Sammelbestellung/Musterlösung|hier]] zu finden
 +
  
  

Aktuelle Version vom 5. März 2013, 17:37 Uhr

Aufgabenstellung

Diese Aufgabe soll möglichst viele Elemente der bisherigen Vorlesungen aufgreifen und verbinden. Die Teilaufgaben fangen leicht an und werden gegen Ende etwas komplexer, so dass Ihr selbst schauen könnt 'wie weit' ihr kommt. Bei Problemen nicht verzagen, Tutor fragen!

Lest Euch die Aufgabe zunächst komplett durch und überlegt, welche Datenstrukturen ihr aufbauen müsst. Macht euch auf einem Blatt Papier einen Plan, welche Funktionalitäten ihr in Funktionen ausgliedern wollt, z.B. Datensatz einfügen, suchen, entfernen, Liste ausgeben, Datei einlesen, etc. damit ihr diese Funktionen in den späteren Aufgaben einfach wieder verwenden könnt.

Die einzelnen Teilaufgaben bauen aufeinander auf und sollten daher in dieser Reihenfolge bearbeitet werden. Bearbeitet jede Teilaufgabe am besten in einem eigenen Unterverzeichnis, so dass ihr am Ende für jede Teilaufgabe eine einzelne Datei mit dem Quellcode habt.


Folgendes Szenario soll mit Hilfe von elektronischer Datenverarbeitung (kurz EDV) gelöst werden:

Eine Gruppe möchte zum Zweck des Sparens von Versandkosten gemeinsam bei einem Onlinehändler bestellen. Dabei soll von allen Bestellern eine Bestellliste im CSV-Format entgegengenommen werden. Diese Einzellisten sollen dann zu einer Gesamtbestellliste zusammengeführt werden, die für jeden Artikel auflistet, wie oft er bestellt wurde. Bestellen mehrere Personen denselben Artikel, so soll dies anhand der Bestellnummer erkannt werden und dieser auf der Gesamtliste natürlich nur einmal, aber mit passender Menge, erscheinen.

Neben dieser Bestellliste soll am Ende eine kurze Liste ausgegeben werden, die angibt wie viele Produkte jeder einzelne Teilnehmer bestellt hat und wie viel Geld er bezahlen muss. Vereinfachung: Die Versandkosten sollen anhand der Menge der Artikel aufgeteilt werden, nicht nach dem Gewicht.

Im Vorfeld ist nicht bekannt, wie viele Personen insgesamt bestellen.

Beachtet bitte die Vorgaben zu dieser Aufgabe, welche ihr hier herunterladen könnt: [1]. (Entpacken mit tar -xzf Sammelbestellung_Vorgaben.tgz (unter Solaris gtar ...) oder einzeln runterladen)

Teil 1

Erweitere die untenstehende Vorgabe so, dass jeder Aufruf der addItem()-Funktion den Artikel in einer einfach verketteten Liste speichert.

Diese Liste soll am Ende des Programms auf dem Bildschirm formatiert ausgegeben werden, nachdem alle Artikel in der Liste gespeichert sind. Dabei spielt die Reihenfolge der Ausgabe keine Rolle, es kann also sowohl an den Anfang wie an das Ende der Liste angehangen werden.

Dazu musst Du zunächst die struct-Definition der Listenelemente sinnvoll festlegen und einige Hilfsfunktionen zum Einfügen in die Liste und Ausgeben der Liste am Ende programmieren:

#include <stdlib.h>

typedef struct litem_t
{
	// ...
} litem;

typedef struct llist_t
{
	struct litem_t *item;
	struct llist_t *next;
} llist;

llist* addItem(llist* alist, char* orderno, char* name, float price, int count, float sum)
{
	// ...
}

// weitere Hilfsfunktionen ...

int main(int argc, char** argv)
{
	// ...
	
	llist *alist; 
	alist= addItem(NULL, "UT 2042 C","40 MHz-Digital-Speicher-Oszilloskop",349.00, 1, 349.00);
	alist= addItem(alist, "AGF 2 SW","Hirschmann-Abgreifklemme 4mm schwarz",5.10,1, 5.10);
	
	// ...
	
	/* ausgeben der Liste: */
	// ...
	
}


Ausgabe:

 Bestellnummer    Name                                  Einzelpreis  Menge Gesamtpreis
 UT 2042 C        40 MHz-Digital-Speicher-Oszilloskop	 349.00         1     349.00 
 AGF 2 SW         Hirschmann-Abgreifklemme 4mm schwarz	   5.10         1       5.10

Teil 2

Schreibe ein Programm, dass eine CSV-Datei 'bestellung.csv' aus dem aktuellen Verzeichnis einliest und auf dem Bildschirm ausgibt, wie viele Artikel bestellt wurden und was diese insgesamt kosten. Das Einlesen der Datei befindet sich bereits ausprogrammiert in der Vorgabe.

Die Artikel sollen dazu zunächst in einer einfach verketteten Liste unsortiert gespeichert werden, danach soll diese Liste vom Anfang durchlaufen werden und die Artikel gezählt sowie der Preis berechnet werden.

Die CSV-Datei hat folgendes Format (Beispiele in den Vorgaben):

Bestellnummer, Kurzbeschreibung, Einzelpreis, Anzahl, Preis
UT 2042 C, 40 MHz-Digital-Speicher-Oszilloskop, 349.00, 1, 349.00 
AGF 2 SW, Hirschmann-Abgreifklemme 4mm schwarz, 5.10,1, 5.10
AK 2 RT, Hirschmann-Krokoklemme 4mm rot, 1.80, 1, 1.80

Teil 3

Stelle nun sicher, dass ein Artikel immer nur einmal in die Liste aufgenommen werden kann. Ist er bereits in der Liste vorhanden, so soll die Anzahl und der Preis angepasst werden. Stelle außerdem sicher, dass beim Einlesen der Liste der Preis jeweils das Produkt aus Anzahl und Einzelpreis ist, und sich keine Fehler in der Bestellliste eingeschlichen haben.

Erweitere nun das Programm so, dass der Dateiname auf der Kommandozeile angegeben werden kann und so nacheinander mehrere Teilbestellungen bearbeitet werden können.

Teil 4

Das Programm soll nun beliebig viele Dateinamen als Kommandozeilenparameter beim Start übergeben bekommen und für jeden einzelnen eine neue Liste führen. Am Ende soll dann in einem Block eine kurze, formatierte Tabelle ausgegeben werden, welche eine Spalte mit dem Dateinamen, dann die Anzahl der Produkte und den Endpreis aus der Bestellung enthält:

Dateiname      Produkte   Gesamtpreis
florian.csv    51         123,51
bastla.csv     12           4,12
tannek.csv      6           1,80
=====================================
SUMME:         69         129,43

Tipps: Nutze Liste von Listen, argv, argc, structs, printf, ...

Teil 5

Erweitere das Programm jetzt schließlich so, dass nach dem kompletten Einlesen der einzelnen Listen die Gesamtbestellliste in eine Datei geschrieben wird. Dazu muss zunächst noch eine verkettete Liste angelegt werden, welche die Gesamtbestellung enthält.

Am Ende soll dann die Tabelle aus Teil 3 auf dem Bildschirm ausgeben werden und eine Datei 'gesamt.csv' im aktuellen Verzeichnis angelegt werden, welche die Gesamtbestellung enthält. Das Dateiformat ist hier exakt wie bei den einzelnen Bestelllisten.

Zusatzaufgabe

Sorge dafür, dass vor dem Beenden des Programms aller Speicher der Liste freigegeben wird. Was ist dabei zu beachten?

Lösung

Eine Teilimplementierung ist hier zu finden


Kommentare

Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf "bearbeiten" und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)