Einführung in die strukturierte Programmierung
Lernziel des zweiten Übungsbeispiels ist die Verwendung von Structs, Pointern und Files anhand eines Programms zu Generierung von Vektorgrafiken zu erlernen.
Im nächsten (letzten) Tutorium wird es ein paar wertvolle Hinweise zu passenden Datenstrukturen für dieses Beispiel und einer sinnvollen Herangehensweise geben. Sie sollten dieses Tutorium also unbedingt besuchen.
Schreiben Sie ein Programm, mit dem Sie auf der Konsole rudimentäre SVG-Dateien http://de.wikipedia.org/wiki/SVG erstellen können. Sie können diese Dateien später mit einem Webbrowser anzeigen.
Das Programm erwartet genau zwei Kommandozeilenparameter. Einer beginnt mit
"-s="gibt einen Default Dateinamen für Speicherungen an. Der zweite beginnt mit
"-c="und gibt den Namen eines Konfigurationsfiles an. Die beiden Parameter können in beliebiger Reihenfolge übergeben werden und dürfen keine Leerzeichen enthalten (da es sonst mehr als zwei Parameter wären). Das Programm gibt danach in einer Endlosschleife einen Standardprompt (z.B.:
"esp>"näheres siehe Konfiguration) aus und wartet auf die Eingabe eines der definierten Befehle. Die Eingabe der Befehle erfolgt case sensitive. Nach Eingabe eines Befehls erfragt das Programm gegebenenfalls die Parameter durch ein eigenes Parameterprompt (jeweils eine Zeile pro Parameter, siehe Beschreibung der Befehle).
Die Konfigurationsdatei ist eine Binärdatei, die der Reihe nach folgende Werte beeinhaltet:
"OffsetX"(int) Offset von Ursprung (linke obere Ecke) der zu allen X-Koordinatenwerten addiert wird
"OffsetY"(int) Offset von Ursprung (linke obere Ecke) der zu allen Y-Koordinatenwerten addiert wird
"Prompt"(char[4]) Buchstabenkombination (gespeichert als drei Zeichen plus \0), welche als Standardprompt gefolgt von ">" ausgegeben wird
"DefWidth"(int) Standardbreite für Rechtecke
"DefHeight"(int) Standardhöhe für Rechtecke
"DefRad"(int) StandardRadius für Kreise
Jeder Befehl besteht aus einem Wort. Nach den meisten Befehlen wird eine Reihe von Parameterprompts ausgegeben. Bei Ausgabe eines Parameterprompts wird kein Standardprompt ausgegeben. Den Parameterprompts werden zwei Leerzeichen vorangestellt (siehe Beispieloutput). Erfolgt bei einem Parameter keine Eingabe (der Benutzer drückt also nur die Entertaste) gelten folgende Szenarien:
"id? "Identifkator (Name) des Objektes (für internen Gebrauch, nicht im SVG-File)
"x1? "X - Koordinate des Startpunktes [px]
"y1? "Y - Koordinate des Startpunktes [px]
"x2? "X - Koordinate des Endpunktes [px]
"y2? "Y - Koordinate des Endpunktes [px]
Bei allen Koordinatenangaben werden die in der Konfiguration angegebenen Offsets (X bzw. Y-Offsets) addiert.
Dieser Befehl erstellt später das äquivalenten SVG-Tag:
"<line x1="X1" y1="Y1" x2="X2" y2="Y2" style="stroke:black;stroke-width:2" />"(Die entsprechenden Werte werden mit den eingegebenen gefüllt)
"id? "Identifkator (Name) des Objektes
"x? "X - Koordinate des linken unteren Punktes des Rechtecks [px]
"y? "Y - Koordinate des linken unteren Punktes des Rechtecks [px]
"width? "Breite des Rechtecks [px]
"height? "Höhe des Rechtecks [px]
"fill? "Farbe des Rechtecks CSS Notation
Bei allen Koordinatenangaben werden die in der Konfiguration angegebenen Offsets (X bzw. Y-Offsets) addiert.
Werden für width und height keine Werte angegeben, so werden die entsprechenden Defaultwerte (siehe Konfiguration) übernommen.
Dieser Befehl erstellt später das äquivalente SVG Tag:
"<rect x="X" y="Y" width="W" height="H" fill="C"/>"
"id? "Identifkator (Name) des Objektes
"cx? "X - Koordinate des Mittelpunktes des Kreises [px]
"cy? "Y - Koordinate des Mittelpunktes des Kreises [px]
"r? "Radius des Kreises [px]
"fill? "Farbe des Kreises [CSS Notation]
Bei allen Koordinatenangaben werden die in der Konfiguration angegebenen Offsets (X bzw. Y-Offsets) addiert.
Werden für Radius kein Wert angegeben, so wird der entsprechende Defaultwert (siehe Konfiguration) übernommen.
Dieser Befehl erstellt später das äquivalente SVG Tag:
"<circle cx="CX" cy="CY" r="R" fill="C"/>"
"id? "Identifkator (Name) des Objektes
"text? "Text der angezeigt werden soll
"x? "X - Koordinate des linken unteren Startpunkt des Textes [px]
"y? "Y - Koordinate des linken unteren Startpunkt des Textes [px]
"font-size? "Texthöhe [px]
"fill? "Farbe des Textes [CSS Notation]
Bei allen Koordinatenangaben werden die in der Konfiguration angegebenen Offsets (X bzw. Y-Offsets) addiert.
Das äquivalente SVG Tag ist:
"<text x="X" y="Y" font-size="S" fill="C">TEXT</text>"
"id? "Identifkator (Name) des Objektes
Bis der Benutzer das Kommando
"e\n"eingibt sollte eine Sequenz von Punkten eingelesen werden.
"x? "X - Koordinate des Punktes im Polygon [px]
"y? "Y - Koordinate des Punktes im Polygon [px]
Nach der Eingabe von "e" muss noch der Prompt zur Eingabe der Füllfarbe angezeigt werden:
"fill? "Farbe des Polygons [CSS Notation]
Bei allen Koordinatenangaben werden die in der Konfiguration angegebenen Offsets (X bzw. Y-Offsets) addiert.
Das äquivalente SVG Tag ist:
"<polygon points="X1 Y1 X2 Y2 ... " fill="C" style="stroke:gray;stroke-width:1" />"
Gibt eine Liste aller angelegten Objekte in Reihenfolge der Eingabe aus. Für jedes Objekt wird ein Präfix ("[li]" für Line, "[re]" für Rectangle, "[ci]" für Circle, "[tx]" für Text oder "[po]" für Polygon), danach ein Leerzeichen gefolgt von dem Objekt-Identifikator und einem Zeilenumbruch ausgegeben.
"id? "Der Benutzer gibt den Namen eines Objektes ein. Dieses wird gelöscht.
Mit der Eingabe von "e\n" kann der Befehl abgebrochen werden.
"file? "Dateiname für die zu erstellende SVG-Datei
"width? "Breite des Bildes [px]
"height? "Höhe des Bildes [px]
Beendet das Programm.
"usage: ex2 -s=savefile -c=configfile\n"
"error: out of memory\n"
"error: cannot read configfile [filename]\n"
"warning: file [filename] exists and will be replaced. Do you want to proceed? (y/n)"
"error: unknown command\n"
"error: invalid parameter - please enter an integer number\n"
"error: id does not exist\n"
"error: id already used\n"
"error: invalid id 'e'\n"
"cannot write to savefile [filename]\n"
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="500" height="500" xmlns="http://www.w3.org/2000/svg">
</svg>
style="stroke:black;stroke-width:2"hinzugefügt werden.
style="stroke:gray;stroke-width:1"hinzugefügt werden.
Dies ist eine beispielhafte Aufteilung auf die Gruppenmitglieder. Sollten Sie eine andere Aufteilung wählen, müssen Sie diese beim Abgabegespräch begründen. Beachten Sie in diesem Fall, dass alle Gruppenmitglieder gleichermaßen an dem Beispiel mitarbeiten müssen und einen annähernd gleichen Aufwand haben sollen.
[essayen@pluto ex2]$ ./ex2 -s=rectangle.svg -c=default.cfg ESP> rect id? Rec1 x? 200 y? 300 width? 100 height? 100 fill? red ESP> save file? width? 500 height? 500 ESP> quit
[schlumpf@pluto c2SVG]$ more rectangle.svg <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="500" height="500" xmlns="http://www.w3.org/2000/svg"> <rect x="200" y="300" width="100" height="100" fill="red" /> </svg>
Bis zum 20.11.2008 23:59:59 vorläufiges Designdokument (dd2.pdf) in einem Archiv namens ex2dd.tar.gz oder ex2dd.zip. Bis zum 11.12.2008 23:59:59 Quellcode (ex2.c) und Designdokument (dd2.pdf) in einem Archiv namens ex2.tar.gz oder ex2.zip.
Wie Sie sicher gemerkt haben, ist diese Aufgabenstellung sehr umfangreich. Obwohl sie bis zur Ausgabe von mehreren Personen nach bestem Wissen und Gewissen kontrolliert wurde, ist es möglich, dass einzelne Aspekte nicht detailliert genug dargestellt sind, oder Informationen fehlen. Bitte lesen Sie daher unbedingt regelmäßig die Newsgroup. Änderungen an der Angabe werden immer mit eigenen Threads von DI Safran beginnend mit "[as] .." bekanntgegeben.
Bei diesem Beispiel gibt es die Möglichkeit, einige Bonuspunkte zu erarbeiten:
Implementieren Sie eine Funktionalität, um eingegebene Farbwerte auf Gültigkeit zu überprüfen. Alle Farbnotationen, die im CSS Standard erlaubt werden, müssen akzeptiert werden. Geben Sie im Fehlerfall die Fehlermeldung:
"error: invalid parameter - please enter a color code\n"
aus.
Implementieren Sie einen Befehl um bestehende Objekte zu editieren.
"id? "Identifkator (Name) des Objektes
danach geben Sie die Parameterprompts für die einzelnen Parameter des Objektes erneut aus. Geben Sie bereits existierende Werte in eckigen Klammern an wie z.B.:
"cx [100]? "X - Koordinate des Mittelpunktes des Kreises [px]
Gibt der Benutzer keine neue Zahl einen sondern betätigt lediglich die Enter-Taste wird der bestehende Wert beibehalten.
Implementieren Sie einen Befehl um ein neues Konfigurationsfile zu schreiben. Das Programm läuft nach Bearbeitung des Befehls normal weiter.
"file? "Dateiname des zu speichernden Konfigurationsfiles
"offsetX? "(int) Offset von Ursprung (linke obere Ecke) der zu allen Koordinatenwerten addiert wird
"offsetY? "(int) Offset von Ursprung (linke obere Ecke) der zu allen Koordinatenwerten addiert wird
"prompt? "(char[4]) Buchstabenkombination (drei Zeichen, abgeschlossen mit \0), welche als Standardprompt gefolgt von ">" ausgegeben wird
"defWidth? "(int) Standardbreite für Rechtecke
"defHeight? "(int) Standardhöhe für Rechtecke
"defRad? "(int) StandardRadius für Kreise