Programmieren in C++ 8. Übung 1. Aufgabe a) Erkläre, warum die folgende C++-Funktion mit einem Speicherfehler versagt: #include <iostream.h> void strcpy(char* s1, char* s2) { int i; for (i = 0; *s2 != '\0'; s2++) s1[i++] = *s2; s1[i] = '\0'; } void main() { char* quelle = "Dies ist eine Zeichenkette"; char* ziel; strcpy(ziel,quelle); cout << ziel << endl; } b) Korrigiere das Programm so, daß es seine beabsichtigte Aufgabe, nämlich das Kopieren einer Zeichenkette in eine andere, richtig ausführt. c) Gib eine Funktion an, die den Vergleich zweier Zeichenketten ermöglicht d) Gib eine Funktion an, die die Länge einer Zeichenkette errechnet e) Überarbeite die Funktion strcpy() . Es sollen mindestens zwei alternative möglichst kurze und effiziente Lösungen gefunden werden, die mit Zeigerarithmetik arbeiten. f) Gib an, wie ein Programm zu schreiben ist bzw. zu implementieren ist, damit der Anwender während der Compilierungszeit wahlweise bestimmen kann, ob die Zeichenkettenfunktionen aus der Standard C-Bibliothek oder aus dem vorliegenden Programm benutzt werden sollen f) Erkläre, warum das folgende Programm zu einer falschen Ausgabe führt. #include <iostream.h> void main() { char str[] = "vermeer"; char* zgstr = str; cout << "Die Adresse von zgstr ist: " << zgstr << endl; } g) Korrigiere das Programm so, daß es seine beabsichtigte Aufgabe richtig ausführt. 2. Aufgabe a) Schreibe eine Funktion char* holeArg(int argc, char* argv[], char option); 1 Programmieren in C++ die aus den beiden Programmparametern argc und argv die durch das Zeichen option definierte Programmoption ermittelt. Alle Optionen sind im Programmaufruf durch ein Minuszeichen markiert. Ein solcher Programmaufruf könnte sein: bsp -a -bxyz -c klm Die Option a ist ein reiner „Schalter“, die Optionen b und c erwarten ein zusätzliches Argument, nämlich xyz bzw. klm. Außerdem ist eine weitere parametrisierte Option d vorgegeben. Dies kann im Programm folgendermaßen analysiert werden: int main(int argc, char* argv[]) { int a = (int) holeArg(argc, argv, char* b_arg = holeArg(argc, argv, char* c_arg = holeArg(argc, argv, char* d_arg = holeArg(argc, argv, .... } ‘a’); ‘b’); ‘c’); ‘d’); // // // // -> -> -> -> wahr „xyz“ „klm“ 0 b) Modifiziere die unter a) angegebene Lösung derart, daß folgendes Hauptprogramm möglich wird int main(int argc, char* argv[]) { int a = (int) holeArg(argc, argv, ‘a’); char* b_arg = holeArg(‘b’); // argc und argv stammen char* c_arg = holeArg(‘c’); // vom ersten Aufruf .... } 3. Aufgabe Gegeben ist das folgende Sortierprogramm: #include <iostream.h> #include <string.h> const int groesseSp = 1000; char* wortSp; void worteLesen(char* z[], int& n) { char* zgrwortSp = wortSp; cout << "\nAnzahl Worte "; cin >> n; cout << "\n" << n << " Worte eingeben: " << endl; for (int i = 0; i < n; i++) { cin >> zgrwortSp; // Einlesen Zeichenkette z[i] = zgrwortSp; // Zuweisen Zeiger auf Zeichenkette zgrwortSp +=strlen(zgrwortSp) + 1; // } } void bubbleSort(char* z[], int n) { char* h; for (int i = 0; i < n - 1; i++) for (int j = n - 1; i < j; j--) if (strcmp(z[j-1], z[j]) > 0) { h = z[j- 1]; z[j - 1] = z[j]; z[j] = h; 2 Programmieren in C++ } } void ausgabe(char* z[], int n) { for (int i = 0; i < n; i++) cout << z[i] << " "; } void main() { const int anzWorte = 50; char* zgrZk[anzWorte]; worteLesen(zgrZk,n); bubbleSort(zgrZk,n); ausgabe(zgrZk,n); return(0); } a) Ändere das vorliegende Sortierprogramm so, daß die beiden Angaben - Anzahl zu lesender Worte - größtmögliche Wortlänge aus der Kommandozeile, d.h. argc und argv eingelesen werden. b) Ändere das Sortierprogramm so, daß die Zeichenketten-Tabelle dynamisch (d.h. während der Laufzeit) beschafft wird. Es ist während der Laufzeit der Speicherplatz zu beschaffen, der zum Speichern der Zeichenkette (Wörter) bei größtmöglicher Kettenlänge, wie unter a) eingelesen, benötigt wird. c) Ändere die Funktionsprozedur worteLesen() so, daß die Worte aus einer existierenden ASCII-Datei (datei.txt) eingelesen werden und im Speicherplatz, der unter b) bereitgestellt wurde, untergebracht werden 4. Aufgabe Der Präfixoperator # des Präprozessors verwandelt sein Argument, einen Makroparameter, in eine Zeichenkette. Verwende das folgende Makro, um in einem kleinen Programm den Speicherbedarf der wichtigsten Datentypen festzustellen. #define p(X) cout << #X “:\t“ << sizeof(X) 5. Aufgabe Schreibe eine Funktion char* strdup(const char* s), die die Zeichenkette s dupliziert, indem neuer Speicherplatz mit new beschafft wird und s in diesen Bereich hineinkopiert wird. Ein Zeiger auf den Beginn des Duplikats soll zurückgegeben werden. 3