Übersicht. Einführung in die Programmierung. Die Standardbibliothek. Ein- und Ausgabe. Ein- und Ausgabe. Dateioperationen.



Ähnliche Dokumente
Aufgaben zur C-Programmierung für die Praktikumsperiode des 1.Semesters

1 Vom Problem zum Programm

FILE *fp; char fname[100];... fp = fopen (fname, rb ); if( fp == NULL ) { perror( fopen );... } // Fehlernachricht auf letzten Fehler, der aufkam

Einführung in die Programmierung

high level I/O/ low level I/O

Fakultät Angewandte Informatik Lehrprofessur für Informatik

Modellierung und Programmierung 1

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2015/2016 Wirtschaftsingenieur Bachelor 5. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

Praktikum Ingenieurinformatik. Termin 2. Verzweigungen (if-else), printf und scanf, while-schleife

Angewandte Mathematik und Programmierung

Informatik Repetitorium SS Volker Jaedicke

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Unterprogramme. Funktionen. Bedeutung von Funktionen in C++ Definition einer Funktion. Definition einer Prozedur

Einführung in die C++ Programmierung für Ingenieure

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Einführung in die Programmierung (EPR)

Dr. Monika Meiler. Inhalt

Programmierkurs Java

Informatik Grundlagen, WS04, Seminar 13

Einführung in die Programmierung

Übungskomplex Felder (1) Eindimensionale Felder Mehrdimensionale Felder

Zählen von Objekten einer bestimmten Klasse

Diana Lange. Generative Gestaltung Operatoren

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Automatisierung ( Fernsteuerung ) von Excel unter Microsoft Windows Tilman Küpper (tilman.kuepper@hm.edu)

Zusammenfassung des Handzettels für Programmieren in C

Programmierung in C. Grundlagen. Stefan Kallerhoff

Klausur in Programmieren

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Objektbasierte Entwicklung

Wir arbeiten mit Zufallszahlen

Ein-/Ausgabe, Dateisystem. Kapitel 9: Ein-/Ausgabe. Programmieren in C für Elektrotechniker. Programmieren in C. Dateisystem. Programmieren in C

Dateioperationen Fachhochschule Würzburg-Schweinfurt Prof. Dr. Martin Ochs. Abspeichern und Einlesen von Texten (Strings) in Dateien

Hochschule München, FK 03 FA SS Ingenieurinformatik

Graphic Coding. Klausur. 9. Februar Kurs A

Einführung in die C-Programmierung

Die elementare Ausgabe von Daten auf externe Medien, wie Dateien und das Einlesen davon wird demonstriert.

Die Programmiersprache C99: Zusammenfassung

M. Graefenhan Übungen zu C. Blatt 3. Musterlösung

Einführung in die Programmierung

C-Probeklausur (Informatik 1; Umfang: C, Teil 1; SS07)

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Objektorientierte Programmierung

Hochschule Ravensburg-Weingarten Schriftliche Prüfung Programmieren Prof. Dr. M. Zeller

Übungsblatt 3: Algorithmen in Java & Grammatiken

2. Semester, 2. Prüfung, Lösung

182. stdio stdio. Eingabe. Ausgabe. Typisch für Zeileneingabe und Analyse: #include <stdio.h>

Felder, Rückblick Mehrdimensionale Felder. Programmieren in C

Deklarationen in C. Prof. Dr. Margarita Esponda

5 DATEN Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu

S7-Hantierungsbausteine für R355, R6000 und R2700

Studentische Lösung zum Übungsblatt Nr. 7

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 18

Übungen Programmieren 1 Felix Rohrer. Übungen

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

Ingenieurinformatik Diplom-FA (C-Programmierung)

Tutorium Informatik 1. Aufgabe 2: Formatierte Ein- und Ausgabe

Institut für Programmierung und Reaktive Systeme 26. April Programmieren II. 10. Übungsblatt

Schnellanleitung: Verbuchung von Studien- und Prüfungsleistungen

Übung 9 - Lösungsvorschlag

Funktionale Programmierung mit Haskell

Modul 122 VBA Scribt.docx

Arge Betriebsinformatik GmbH & Co.KG, CAP News 40, Februar CAP-News 40

Auswahlabfragen mit ACCESS

Übung Grundlagen der Programmierung. Übung 05: Arrays. Abgabetermin: xx.xx.xxxx. Java-Programm Testplan Testergebnisse

2. Programmierung in C

Dateiname Name(n) und Matrikelnr. des/der Bearbeiter Tel.-Nr. und -Adresse für den Fall, dass die Diskette nicht lesbar ist.

Einführung in die Java- Programmierung

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

Datenbanken Kapitel 2

IT-Zertifikat: Allgemeine Informationstechnologien II PHP

I.1 Die Parrot Assemblersprache

PHP - Projekt Personalverwaltung. Erstellt von James Schüpbach

Testklausur 1 zur Vorlesung. Modellierung und Programmierung I. Dr. Monika Meiler Zeit: 60 Minuten

Access Grundlagen für Anwender. Andrea Weikert 1. Ausgabe, 1. Aktualisierung, Juli inkl. zusätzlichem Übungsanhang ACC2010-UA

Programmiersprachen Einführung in C

Matrix42. Use Case - Sicherung und Rücksicherung persönlicher Einstellungen über Personal Backup. Version September

Vorkurs C++ Programmierung

50. Mathematik-Olympiade 2. Stufe (Regionalrunde) Klasse Lösung 10 Punkte

10 Lesen und Schreiben von Dateien

Die Programmiersprache C

Grundlagen der Informatik I Informationsdarstellung

1. Aktionen-Palette durch "Fenster /Aktionen ALT+F9" öffnen. 2. Anlegen eines neuen Set über "Neues Set..." (über das kleine Dreieck zu erreichen)

Computerarithmetik ( )

Programmiersprachen Einführung in C. Unser erstes C-Programm. Unser erstes C-Programm. Unser erstes C-Programm. Unser erstes C-Programm

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Kontrollstrukturen und Funktionen in C

Windows. Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1

CMS.R. Bedienungsanleitung. Modul Cron. Copyright CMS.R Revision 1

Erwin Grüner

Programmieren in C. Felder, Schleifen und Fließkommaarithmetik. Prof. Dr. Nikolaus Wulff

Systeme 1. Kapitel 6. Nebenläufigkeit und wechselseitiger Ausschluss

25 kann ohne Rest durch 5 geteilt werden! ist wahr

Ausgewählte Bibliotheksfunktionen

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

C allgemein. C wurde unter und für Unix entwickelt. Vorläufer sind BCPL und B.

Grundlagen der Programmierung Prof. H. Mössenböck. 3. Verzweigungen

E-/A-Funktionalität nicht Teil der Programmiersprache

Transkript:

Übersicht Einführung in die Programmierung Bachelor of Science Prof. Dr. Rethmann Fachbereich Elektrotechnik und Informatik Hochschule Niederrhein Arrays Datentypen, Operatoren und Kontrollstrukturen Funktionen und Zeiger Zeichenketten und Strukturen die Standardbibliothek strukturierte Programmierung modulare Programmierung WS 2009/10 Einführung in die Programmierung Standardbibliothek 2 / 69 Die Standardbibliothek gutes für prozedurale Programmierung und wiederverwendbarer Software Definitionsdateien können in beliebiger Reihenfolge mittels #include eingefügt werden. Eine Definitionsdatei muss eingefügt sein, bevor irgendetwas benutzt wird, das in der Header-Datei vereinbart wird. Übersicht Hilfsfunktionen Zeichenketten Zufallszahlen Einführung in die Programmierung Standardbibliothek 3 / 69 Ein- und Ausgabe ein Datenstrom (stream) ist Quelle oder Ziel von Daten und wird mit einem Peripheriegerät verknüpft zwei Arten von Datenströmen werden unterschieden: für Text: eine Folge von Zeilen, jede Zeile enthält beliebig viele Zeichen und ist mit \n abgeschlossen für binäre Informationen: eine Folge von Bytes zur Darstellung interner Daten Einführung in die Programmierung Standardbibliothek 4 / 69 Ein- und Ausgabe Ein Datenstrom wird durch Öffnen (open) mit der Datei/dem Gerät verbunden, Schließen (close) von der Datei/dem Gerät getrennt. Öffnet man eine Datei, erhält man einen Zeiger auf ein Objekt von Typ FILE. Das FILE-Objekt enthält alle Informationen, die zur Kontrolle des Datenstroms notwendig sind. Beim Programmstart sind die Datenströme stdin, stdout und stderr bereits geöffnet. Einführung in die Programmierung Standardbibliothek 5 / 69 FILE *fopen(const char *filename, const char *mode) fopen öffnet die angegebene Datei und liefert einen Datenstrom oder NULL bei Misserfolg. Zu den erlaubten Werten von mode gehören: r zum Lesen öffnen (read) w zum Schreiben öffnen, alten Inhalt wegwerfen (write) a zum Anfügen öffnen bzw. erzeugen (append) Wird an die Zeichen ein b angehängt, dann wird auf eine binäre Datei zugegriffen, sonst auf eine Textdatei. Einführung in die Programmierung Standardbibliothek 6 / 69 int fflush(file *stream) gepufferte, aber noch nicht geschriebene Daten werden geschrieben liefert EOF bei einem Schreibfehler, sonst 0 int fclose(file *stream) schreibt noch nicht geschriebene Daten wirft noch nicht gelesene, gepufferte Daten weg gibt automatisch angelegte Puffer frei schließt den Datenstrom liefert EOF bei Fehlern, sonst 0 Einführung in die Programmierung Standardbibliothek 7 / 69 Einführung in die Programmierung Standardbibliothek 8 / 69

int remove(const char *filename) entfernt die angegebene Datei liefert bei Fehlern einen Wert ungleich 0 int rename(const char *oldname, const char *newname) ändert den Namen einer Datei liefert im Fehlerfall einen Wert ungleich 0 FILE *tmpfile(void) erzeugt eine temporäre Datei (automatisches Löschen bei fclose oder normalem Programmende) liefert einen Datenstrom oder NULL im Fehlerfall Formatierte Ausgabe int fprintf(file *file, const char *format,...) wandelt die Ausgaben entsprechend format um schreibt in den angegebenen Datenstrom Resultat: Anzahl der geschriebenen Zeichen, negativer Wert im Fehlerfall Typangaben: c char d int f float s Zeichenkette (String) p Pointer analog zu printf Einführung in die Programmierung Standardbibliothek 9 / 69 Formatierte Eingabe int fscanf(file *file, const char *format,...) liest vom Datenstrom file unter Kontrolle von format legt die umgewandelten Werte in den Argumenten ab alle Argumente müssen Zeiger sein ist beendet, wenn format abgearbeitet ist oder eine Umwandlung nicht durchgeführt werden kann liefert EOF, wenn vor der ersten Umwandlung das Dateiende erreicht wird oder ein Fehler passiert, ansonsten die Anzahl umgewandelter und abgelegter Eingaben analog zu scanf liest über Zeilengrenzen hinweg, um seine Eingabe zu finden Einführung in die Programmierung Standardbibliothek 10 / 69 Fehlerbehandlung Viele der IO-Bibliotheksfunktionen notieren, ob ein Dateiende gefunden wurde oder ein Fehler aufgetreten ist: void clearerr(file *file) löscht die Notizen über Dateiende und Fehler für den Datenstrom file. int feof(file *file) liefert einen Wert ungleich 0, wenn für file ein Dateiende notiert ist. int ferror(file *file) liefert einen Wert ungleich 0, wenn für file ein Fehler notiert ist. In errno.h ist eine global gültige Variable errno definiert. Sie enthält eine Fehlernummer, die Informationen über den zuletzt aufgetretenen Fehler zulässt. Einführung in die Programmierung Standardbibliothek 11 / 69 Fehlerbehandlung void perror(const char *s) gibt s und eine von der Implementierung definierte Fehlermeldung aus, die sich auf den Wert in errno bezieht. void main(void) { f = fopen("test.txt", "r"); if (f == NULL) perror("test.txt"); else fclose(f); Wenn die angegebene Datei nicht gefunden wird, erhalten wir hier die Ausgabe: test.txt: No such file or directory Einführung in die Programmierung Standardbibliothek 12 / 69 Ziel: Eine Liste von Studenten in einer Datei abspeichern und aus einer Datei lesen. # include <stdlib.h> typedef struct { int tag, monat, jahr; date_t; typedef struct { char name[30], vname[30]; date_t gebdat; short fb; long matnr; stud_t; Einführung in die Programmierung Standardbibliothek 13 / 69 int savetofile(stud_t *s, int n, char *fname) { int i; if ((f = fopen(fname, "w")) == NULL) { return 1; fprintf(f, "%d\n", n); // Header: Anzahl Daten for (i = 0; i < n; i++) fprintf(f,"%s %s %02d.%02d.%4d,%hd,%08ld\n", s[i].name, s[i].vname, s[i].gebdat.tag, s[i].gebdat.monat, s[i].gebdat.jahr, s[i].fb, s[i].matnr); return (fclose(f) == EOF? 2 : 0); Einführung in die Programmierung Standardbibliothek 15 / 69 Einführung in die Programmierung Standardbibliothek 14 / 69 stud_t *readfromfile(char *fname, int *len) { stud_t *s; int i; f = fopen(fname, "r"); if (f == NULL) { return NULL; /* Anzahl Daten aus Header lesen */ fscanf(f, "%d", len); /* dynamisches Array anlegen */ s = (stud_t *) malloc(*len * sizeof(stud_t)); Einführung in die Programmierung Standardbibliothek 16 / 69

// einlesen der Daten ( ohne Fehlerbehandlung) for (i = 0; i < *len &&!error; i++) fscanf(f, "%s%s%d.%d.%d,%hd,%ld", s[i].name, s[i]. vname, &s[i].gebdat.tag, &s[i].gebdat.monat, &s[i].gebdat.jahr, &s[i].fb, &s[i].matnr); fclose(f); return s; /* End: readfromfile() */ int main(void) { int i, len; stud_t *t; stud_t s[3] = { {"Huber", "Hans", {23, 5, 1984, 3, 12345678, {"Mayer", "Gabi", {12, 9, 1982, 4, 7654321, {"Meier", "Rosi", {17, 2, 1983, 4, 98761234 ; savetofile(s, 3, "_student.txt"); Einführung in die Programmierung Standardbibliothek 17 / 69 t = readfromfile("_student.txt", &len); for (i = 0; i < len; i++) printf("%s %s %02d.%02d.%4d,%hd,%08ld\n", t[i].name, t[i].vname, t[i].gebdat.tag, t[i].gebdat.monat, t[i].gebdat.jahr, t[i].fb, t[i].matnr); free(t); Problem: es wird jeweils nur der erste Vorname geliefert, da das Einlesen bei einem Leerzeichen abgebrochen wird. Lösung??? siehe strtok() Einführung in die Programmierung Standardbibliothek 18 / 69 Ein- und Ausgabe von Zeichen int fgetc(file *file) liefert das nächste Zeichen des Datenstroms als unsigned char (umgewandelt in int) im Fehlerfall oder bei Dateiende EOF char *fgets(char *s, int n, FILE *file) liest höchstens die nächsten n-1 Zeichen in s ein hört vorher auf, wenn ein Zeilentrenner gefunden wird der Zeilentrenner wird im Vektor abgelegt der Vektor wird mit \0 abgeschlossen liefert NULL bei Dateiende oder im Fehlerfall, ansonsten s Einführung in die Programmierung Standardbibliothek 19 / 69 Ein- und Ausgabe von Zeichen int fputc(int c, FILE *file) schreibt das Zeichen c (umgewandelt in unsigned char) in den Datenstrom liefert das ausgegebene Zeichen, im Fehlerfall EOF int fputs(const char *s, FILE *file) schreibt die Zeichenkette s in den Datenstrom liefert einen nicht-negativen Wert, im Fehlerfall EOF Einführung in die Programmierung Standardbibliothek 20 / 69 Häufigkeit der Buchstaben in einem Text bestimmen. int getindex(char c) { /* aus Klein- mach Grossbuchstabe */ if (c >= a && c <= z ) c -= a - A ; /* alle anderen Zeichen ausschliessen */ if (c < A c > Z ) /* A..Z auf 0..25 abbilden */ return c - A ; Einführung in die Programmierung Standardbibliothek 21 / 69 int main(int argc, char *argv[]) { int i, H[26] = {0; char c, *filename = "_test.txt"; FILE *file; Einführung in die Programmierung Standardbibliothek 22 / 69 while ((c = fgetc(file))!= EOF) { if ((i = getindex(c)) >= 0) H[i] += 1; if (argc > 1) filename = argv[1]; printf("untersuche Datei %s!\n", filename); if (!(file = fopen(filename, "r"))) { perror( filename); return 1;... fclose(file); for (i = 0, c = a ; c <= z ; i++, c++) printf("h[%c] = %d\n", c, H[i]); Einführung in die Programmierung Standardbibliothek 23 / 69 Einführung in die Programmierung Standardbibliothek 24 / 69

anwenden des obigen Programms auf Dies ist nur ein kleiner Test zur Ermittlung von Häufigkeiten der einzelnen Buchstaben. Probleme machen eventuell deutsche Umlaute, denn die werden nicht gezählt. liefert H[a] = 3 H[g] = 3 H[m] = 4 H[s] = 5 H[y] = 0 H[b] = 3 H[h] = 6 H[n] = 16 H[t] = 12 H[z] = 3 H[c] = 4 H[i] = 10 H[o] = 2 H[u] = 9 H[d] = 6 H[j] = 0 H[p] = 1 H[v] = 2 H[e] = 27 H[k] = 2 H[q] = 0 H[w] = 1 H[f] = 1 H[l] = 8 H[r] = 7 H[x] = 0 Einführung in die Programmierung Standardbibliothek 25 / 69 Direkte Ein- und Ausgabe Vorteile von Textdateien: mit Editor lesbar und änderbar plattformunabhängig Nachteile von Textdateien: hoher Speicherplatzbedarf hohe Zugriffszeiten nur auf char und char * kann direkt zugegriffen werden, alle anderen Datentypen müssen konvertiert werden Achtung: Bei fwrite werden nur die Werte von Zeigern gespeichert, nicht der Inhalt, auf den der Zeiger zeigt! Direkte Ein- und Ausgabe size_t fread(void *ptr, size_t size, size_t nobj, FILE *file) liest aus dem Datenstrom in den Vektor ptr höchstens nobj Objekte der Größe size ein liefert die Anzahl der eingelesenen Objekte der Zustand des Datenstroms kann mit feof und ferror untersucht werden size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *file) schreibt nobj Objekte der Größe size aus dem Vektor ptr in den Datenstrom liefert die Anzahl der ausgegebenen Objekte Einführung in die Programmierung Standardbibliothek 26 / 69 int savetofile(stud_t *s, int n, char *fname) { int x; FILE *file; file = fopen(fname, "wb"); if (file == NULL) x = fwrite(s, sizeof(stud_t), n, file); if (x!= n) return fclose(file); Einführung in die Programmierung Standardbibliothek 27 / 69 int readfromfile(stud_t *s, int n, char *fname) { int x; FILE *file; file = fopen(fname, "rb"); if (file == NULL) x = fread(s, sizeof(stud_t), n, file); if (x!= n) return fclose(file); Einführung in die Programmierung Standardbibliothek 28 / 69 int main(void) { stud_t stud[5], *s;... savetofile(stud, 5, filename); s = (stud_t *) malloc(5 * sizeof(stud_t)); readfromfile(s, 5, filename); for (i = 0; i < 5; i++) printf("%s %s %02d.%02d.%4d,%hd,%ld\n", s[i].name, s[i].vname, s[i].gebdat.tag, s[i].gebdat.monat, s[i].gebdat.jahr, s[i].fb, s[i].matrikelnr); Einführung in die Programmierung Standardbibliothek 29 / 69 Positionieren in Dateien int fseek(file *file, long offset, int origin) Dateiposition für file setzen, nachfolgende Lese- oder Schreiboperation greift auf Daten ab dieser Position zu. neue Position ergibt sich aus Addition von offset Bytes zu origin mögliche Werte für origin: Dateianfang SEEK SET, aktuelle Position SEEK CUR, Dateiende SEEK END liefert einen von 0 verschiedenen Wert bei Fehler long ftell(file *file) liefert die aktuelle Dateiposition oder -1L bei Fehler Einführung in die Programmierung Standardbibliothek 30 / 69 Positionieren in Dateien void rewind(file *file) analog zu fseek(file, 0L, SEEK SET); und anschließendem clearerr(file); int fgetpos(file *file, fpos t *ptr) speichert aktuelle Position für den Datenstrom bei *ptr liefert einen von 0 verschiedenen Wert bei Fehler int fsetpos(file *file, const fpos t *ptr) positioniert file auf die Position, die von fgetpos in *ptr abgelegt wurde liefert einen von 0 verschiedenen Wert bei Fehler Einführung in die Programmierung Standardbibliothek 31 / 69 Einführung in die Programmierung Standardbibliothek 32 / 69

int main(void) { int z; char line[10]; // feste Satzlaenge: 10 FILE * file; // keine Fehlerbehandlung Übersicht Hilfsfunktionen Zeichenketten Zufallszahlen file = fopen("_seek.txt", "r"); printf("gehe zu Zeile "); scanf("%d", &z); fseek(file, (z-1) * 10, SEEK_SET); fgets(line, 10, file); printf("%s\n", line); fclose(file); Einführung in die Programmierung Standardbibliothek 33 / 69 Tests für Zeichenklassen: ctype.h Funktionen zum Testen von Zeichen. Jede Funktion hat ein int-argument, dessen Wert entweder EOF ist oder als unsigned char dargestellt werden kann. hat den Rückgabetyp int. liefert einen Wert ungleich 0, wenn das Argument die beschriebene Bedingung erfüllt. Zusätzlich: Funktionen zur Umwandlung zwischen Groß- und Kleinbuchstaben. tolower(c) Umwandlung in Kleinbuchstaben toupper(c) Umwandlung in Großbuchstaben Einführung in die Programmierung Standardbibliothek Hilfsfunktionen 34 / 69 Tests für Zeichenklassen Funktion Beschreibung isalnum(c) isalpha(c) oder isdigit(c) ist erfüllt isalpha(c) isupper(c) oder islower(c) ist erfüllt iscntrl(c) Steuerzeichen isdigit(c) dezimale Ziffer isgraph(c) sichtbares Zeichen, kein Leerzeichen islower(c) Kleinbuchstabe, kein Umlaut oder ß isprint(c) sichtbares Zeichen, auch Leerzeichen isspace(c) Leerzeichen, Seitenvorschub,... isupper(c) Großbuchstabe, kein Umlaut oder ß isxdigit(c) hexadezimale Ziffer Einführung in die Programmierung Standardbibliothek Hilfsfunktionen 35 / 69 Zeichenketten umwandeln in Zahlen: stdlib.h double strtod(const char *str, char **endp) und long strtol(const char *str, char **endp, int base) wandeln den Anfang der Zeichenkette str in double/long um, dabei wird Zwischenraum am Anfang ignoriert. strtoul analog zu strtol, Resultattyp unsigned long Die Funktionen speichern einen Zeiger auf den nicht umgewandelten Rest der Zeichenkette bei *endp. Wert von base: 2,...,36. Umwandlung erfolgt unter der Annahme, das die Eingabe in dieser Basis repräsentiert ist. Einführung in die Programmierung Standardbibliothek Hilfsfunktionen 36 / 69 Erinnerung: call by reference Warum ist endp als Zeiger auf Zeiger auf char definiert? double d; char *r = NULL; char *s = "12.3abc"; d = strtod(s, r); main strtod d r s str endp 4711 4711 // falsch!!!!!! 4711 1 2. 3 a b \0 Einführung in die Programmierung Standardbibliothek Hilfsfunktionen 37 / 69 Erinnerung: call by reference Damit der Wert von r in der Funktion strtod geändert werden kann, muss die Adresse von r übergeben werden! d = strtod(s, &r); main 0815 d r s 4711 strtod str endp 47110815 // richtig!!!!!! 4711 1 2. 3 a b \0 Einführung in die Programmierung Standardbibliothek Hilfsfunktionen 39 / 69 Einführung in die Programmierung Standardbibliothek Hilfsfunktionen 38 / 69... int i; long l; char *r; double d; for (i = 1; i < argc; i += 2) { if (strcmp(argv[i], "-d") == 0) { d = strtod(argv[i + 1], &r); printf("%d. Parameter: %lf\n", i+1, d); else if (strcmp(argv[i], "-l") == 0) { l = strtol(argv[i + 1], &r, 0); printf("%d. Parameter: %ld\n", i+1, l); printf("nicht umgewandelt: %s\n", r);... Einführung in die Programmierung Standardbibliothek Hilfsfunktionen 40 / 69

Obiges Programm liefert bei dem Aufruf strumw -d 12.3ab -l 789.1cd -l 0X23AGH -l 022.2xy die folgende Ausgabe: 2. Parameter: 12.300000 Nicht umgewandelt: ab 4. Parameter: 789 Nicht umgewandelt:.1cd 6. Parameter: 570 Nicht umgewandelt: GH 8. Parameter: 18 Nicht umgewandelt:.2xy Einfache Umwandlung von Zeichenketten double atof(const char *s) wandelt s in double um analog zu strtod(s, (char **)NULL) int atoi(const char *s) wandelt s in int um analog zu (int)strtol(s, (char **)NULL, 10) int atol(const char *s) wandelt s in long um analog zu strtol(s, (char **)NULL, 10) base = 0 übliche Interpretation für int-konstanten Einführung in die Programmierung Standardbibliothek Hilfsfunktionen 41 / 69... int main(int argc, char *argv[]) { int i, *arr; argc -= 1; arr = (int *) malloc(argc * sizeof(int)); for (i = 0; i < argc; i++) arr[i] = atoi(argv[i + 1]); Einführung in die Programmierung Standardbibliothek Hilfsfunktionen 42 / 69 Übersicht Hilfsfunktionen Zeichenketten Zufallszahlen sort(arr, argc); for (i = 0; i < argc; i++) printf("%d\n", arr[i]); Einführung in die Programmierung Standardbibliothek Hilfsfunktionen 43 / 69 Funktionen für Zeichenketten: string.h char *strcpy(char *s, const char *ct) Zeichenkette ct in Vektor s kopieren, liefert s char *strncpy(char *s, const char *ct, int n) maximal n Zeichen aus ct in Vektor s kopieren, liefert s char *strcat(char *s, const char *ct) Zeichenkette ct an Zeichenkette s anhängen, liefert s char *strncat(char *s, const char *ct, int n) höchstens n Zeichen von ct an Zeichenkette s anhängen und mit \0 abschließen, liefert s Einführung in die Programmierung Standardbibliothek Zeichenketten 44 / 69 Funktionen für Zeichenketten int strcmp(const char *cs, const char *ct) Zeichenketten cs und ct vergleichen: liefert Wert < 0 wenn cs < ct, liefert 0 wenn cs == ct und liefert Wert > 0 wenn cs > ct. int strncmp(const char *cs, const char *ct, int n) höchstens n Zeichen von cs mit ct vergleichen char *strchr(const char *cs, int c) liefert Zeiger auf das erste c in cs, oder NULL char *strrchr(const char *cs, int c) liefert Zeiger auf das letzte c in cs, oder NULL Einführung in die Programmierung Standardbibliothek Zeichenketten 45 / 69 Funktionen für Zeichenketten char *strstr(const char *cs, const char *ct) liefert Zeiger auf erste Kopie von ct in cs, oder NULL. size t strlen(const char *cs) liefert die Länge von cs (ohne \0 ) Einführung in die Programmierung Standardbibliothek Zeichenketten 46 / 69 Funktionen für Zeichenketten char *strerror(int n) liefert Zeiger auf Zeichenkette, die in der Implementierung für Fehler n definiert ist. Anwendung: strerror(errno) : for (i = 0; i < 5; i++) printf("%s\n", strerror(i)); liefert: Success Operation not permitted No such file or directory No such process Interrupted system call Einführung in die Programmierung Standardbibliothek Zeichenketten 47 / 69 Einführung in die Programmierung Standardbibliothek Zeichenketten 48 / 69

grep [-i] pattern file print lines matching [ignore-case] a pattern # include <ctype.h> # include <string.h> char *uppercase(char *word) { int i, len; len = strlen(word); for (i = 0; i < len; i++) word[i] = toupper(word[i]); return word; #define TRUE 1 #define FALSE 0 #define N 80 int main(int argc, char **argv) { FILE *file; int cnt, idx; char ignorecase, pattern[n], line[n]; /* Aufruf formal korrekt? */ if ((argc!= 3) && (argc!= 4)) { printf("try: %s [-i] pattern file\n", argv[0]); return 1; Einführung in die Programmierung Standardbibliothek Zeichenketten 49 / 69 /* ignore-case? */ if (strcmp(argv[1], "-i")) { ignorecase = FALSE; idx = 2; strcpy(pattern, argv[1]); else { ignorecase = TRUE; idx = 3; strcpy(pattern, uppercase(argv[2])); Einführung in die Programmierung Standardbibliothek Zeichenketten 50 / 69 /* Zeilenweise testen */ cnt = 0; while (fgets(line, N, file)) { cnt += 1; if (ignorecase) { if (strstr(uppercase(line), pattern)) printf("%3d: %s", cnt, line); else if (strstr(line, pattern)) printf("%3d: %s", cnt, line); file = fopen(argv[idx], "r"); if (file == NULL) { perror(argv[idx]); return 2; fclose(file); Einführung in die Programmierung Standardbibliothek Zeichenketten 51 / 69 Funktionen für Zeichenketten char *strtok(char *s, const char *ct) durchsucht s nach Zeichenfolgen, die durch Zeichen aus ct begrenzt sind. Der erste Aufruf findet die erste Zeichenfolge in s, die nicht aus Zeichen in ct besteht. Die Folge wird abgeschlossen, indem das nächste Zeichen in s mit \0 überschrieben wird. Resultat: Zeiger auf die Zeichenfolge. Bei jedem weiteren Aufruf wird NULL anstelle von s übergeben. Solch ein Aufruf liefert die nächste Zeichenfolge, wobei unmittelbar nach dem Ende der vorhergehenden Suche begonnen wird. Hinweis: Die Zeichenkette ct kann bei jedem Aufruf verschieden sein. Einführung in die Programmierung Standardbibliothek Zeichenketten 53 / 69 /* Anzahl Daten aus Header lesen */ fgets(line, 200, f); *len = atoi(line); /* dynamisches Array anlegen */ s = (stud_t *) malloc(*len * sizeof(stud_t)); for (i = 0; i < *len; i++) { fgets(line, 200, f); /* Name und Vorname extrahieren */ str = strtok(line, ",:;"); strncpy(s[i].name, str, 30); strncpy(s[i].vname, str, 30); Einführung in die Programmierung Standardbibliothek Zeichenketten 55 / 69 Einführung in die Programmierung Standardbibliothek Zeichenketten 52 / 69 Abspeichern der Studentendaten als CSV-Datei: Huber,Hans Walter,23,5,1978,3,12345678 Meier,Ulrike Maria,12,8,1977,4,07654321 Dazu muss die Methode readfromfile() angepasst werden: stud_t *readfromfile(char *fname, int *len) { stud_t *s; int i; char *str, line[200]; f = fopen(fname, "r"); if (f == NULL) { return NULL; Einführung in die Programmierung Standardbibliothek Zeichenketten 54 / 69 /* Geburtsdatum extrahieren */ s[i].gebdat.tag = atoi(str); s[i].gebdat.monat = atoi(str); s[i].gebdat.jahr = atoi(str); /* Fachbereich und Matrikelnummer */ s[i].fb = atoi(str); s[i].matrikelnr = atoi(str); fclose(f); return s; /* End: readfromfile() */ Einführung in die Programmierung Standardbibliothek Zeichenketten 56 / 69

Vollständiges Schneller Zugriff durch Index: erster Buchstabe des Namens Voraussetzung: sortierte Datensätze, keine Umlaute Vollständiges void main(void) { char c; # include <string.h> # include <ctype.h> # define LENGTH 100 createindex("_student.txt"); printf("erster Buchstabe des Namens: "); scanf("%c", &c); printstudents(c, "_student. txt"); int len[26] = {0; int createindex(char *filename); void printstudents(char c, char *filename); int getindex(char c); void toscreen(char *data); int getindex(char c) { int e, i, idx = 0; e = tolower(c) - a ; for (i = 0; i < e; i++) idx += len[i]; return idx; Einführung in die Programmierung Standardbibliothek Zeichenketten 57 / 69 Vollständiges int createindex(char *filename) { char line[length]; f = fopen(filename, "r"); if (f == NULL) { perror( filename); while (fgets(line, LENGTH, f)) { char c = tolower(line[0]); len[c - a ] += strlen(line); return fclose(f); Einführung in die Programmierung Standardbibliothek Zeichenketten 59 / 69 Vollständiges void toscreen(char *data) { char name[30], vname[30]; int tag, monat, jahr; short fb; long matrikelnr; Einführung in die Programmierung Standardbibliothek Zeichenketten 58 / 69 Vollständiges void printstudents(char c, char *filename) { char line[length]; int idx = getindex(c); f = fopen(filename, "r"); if (f == NULL) { perror( filename); fseek(f, idx, SEEK_SET); // Fehlerbehandlung? while (fgets(line, LENGTH, f) && toupper(line[0]) == toupper(c)) toscreen(line); fclose(f); Einführung in die Programmierung Standardbibliothek Zeichenketten 60 / 69 Übersicht Hilfsfunktionen Zeichenketten Zufallszahlen strcpy(name, strtok(data, ";,:")); strcpy(vname, strtok(null, ";,:")); tag = atoi(strtok(null, ";,:")); monat = atoi(strtok(null, ";,:")); jahr = atoi(strtok(null, ";,:")); fb = atoi(strtok(null, ";,:")); matrikelnr = atol(strtok(null, ";,:")); printf("%s, %s, %02d.%02d.%4d, %hd, %ld\n", name, vname, tag, monat, jahr, fb, matrikelnr); Einführung in die Programmierung Standardbibliothek Zeichenketten 61 / 69 Pseudo-Zufallszahlen Die Kennzeichen einer Zufallsfolge sind: Zahlen entstammen einem gegebenen Zahlenbereich. Zahlen sind unabhängig voneinander: aus der Kenntnis der ersten n Zahlen kann nicht auf die (n+1)-te Zahl geschlossen werden. Zahlen unterliegen gegebener Häufigkeitsverteilung. : Würfel Zahlen im Bereich 1 bis 6 Gleichverteilung: Würfelt man genügend häufig, dann zeigt sich, dass die Zahlen 1 bis 6 ungefähr gleich oft erscheinen. Einführung in die Programmierung Standardbibliothek Zufallszahlen 62 / 69 Pseudo-Zufallszahlen Einfache Zufallszahlen zwischen 0 und m: x 0 [0...m 1] wird vorgegeben seed x n+1 = (a x n + 1) mod m : x n+1 = (3423 x n + 1) mod 2 16 Die ersten 42 Werte für x 0 = 0: 0 1 3424 54945 53952 62785 20512 23521 34176 2689 29408 289 6208 16321 30112 50785 35584 38145 22624 43937 56768 2625 6944 45281 4224 40833 48608 54817 9024 21697 16544 7009 5632 10753 41824 32929 59584 8001 58912 1505 39808 13441 Einführung in die Programmierung Standardbibliothek Zufallszahlen 63 / 69 Einführung in die Programmierung Standardbibliothek Zufallszahlen 64 / 69

Pseudo-Zufallszahlen Güte: Stelle je zwei Zufallszahlen als Koordinaten x, y dar. Bei guter Gleichverteilung ist das resultierende Bild gleich dicht mit Punkten gefüllt. obige Folge ist schlecht! 70000 60000 50000 40000 30000 20000 10000 0 0 10000 20000 30000 40000 50000 60000 70000 Einführung in die Programmierung Standardbibliothek Zufallszahlen 65 / 69 Pseudo-Zufallszahlen Das obige graphische Verfahren soll das Problem der Güte von Zufallszahlen-Generatoren nur veranschaulichen. Gute Generatoren sollten folgende Kriterien erfüllen: große Periode geringe Korrelation gleichmäßige Verteilung Portierbarkeit lange sich nicht überschneidende Teilfolgen Wiederholbarkeit Aus der Mathematik sind geeignete Tests für die Güte von Zufallszahlengeneratoren bekannt. Entropietest Chi-Quadrat-Test Pseudo-Zufallszahlen Gut: modifizierte Zufallsfolge x n+1 = (3421 x n + 1) mod 2 16 mit x 0 = 0. 70000 60000 50000 40000 30000 20000 10000 0 0 10000 20000 30000 40000 50000 60000 70000 Einführung in die Programmierung Standardbibliothek Zufallszahlen 66 / 69 Pseudo-Zufallszahlen in C int rand(void) liefert eine ganzzahlige Pseudo-Zufallszahl im Bereich von 0 bis RAND MAX (mindestens 32767 = 2 15 1, ebenfalls definiert in stdlib.h) void srand(unsigned int seed) benutzt seed als Ausgangswert für eine neue Folge von Pseudo-Zufallszahlen (entspricht x 0 ) Die Güte des in C verwendeten Zufallszahlengenerators ist für normale Anwendungen ausreichend. siehe auch D.E. Knuth: The art of computer programming, Volume 2. Einführung in die Programmierung Standardbibliothek Zufallszahlen 67 / 69 Einführung in die Programmierung Standardbibliothek Zufallszahlen 68 / 69 # include <stdlib.h> #define N 10000 int main(void) { int i, arr[n]; int seed = 1; srand(seed); for (i = 0; i < N; i += 2) { arr[i] = rand() % 200; arr[i + 1] = rand() % 200; printf("%3d, %3d\n", arr[i], arr[i + 1]); printf("\n"); Einführung in die Programmierung Standardbibliothek Zufallszahlen 69 / 69