ein Kapitel zurück                                           ein Kapitel weiter

Wie die Funktionen printf und scanf stehen zur formatierten Ein- und Ausgabe die Funktionen fprintf und fscanf zur Bearbeitung von Dateien zur Verfügung. Mit dem einzigen Unterschied das diese noch einen zusätzlichen Parameter vom Typ FILE * in der Parameterliste enthalten. Hier der Syntax....

int fprintf(FILE *f, const char *format, ...);
int fscanf(FILE *f, const char *format, ...);

Zum Beispiel ist......

fscanf(stdin,"%d",&x);

.....Daselbe wie.....

scanf("%d",&x);

Beide lesen von der Standarteingabe (stdin) einen Wert vom Format %d, also einen Integerwert. Somit ist natürlich.....

fprintf(stdout,"Hallo Welt\n");

...ebenfalls das selbe wie...

printf("Hallo Welt\n");

Beide schreiben den String "Hallo Welt" in die Standardausgabe (stdout). Zu stdin, stdout und stderr gibt es im nächsten Kapitel eine Ausführlichere Erklärung. fscanf() und fprintf() lassen sich also genauso anwenden wie scanf() und printf() nur mit dem Unterschied das die entsprechende Datei (FILE*) mitangegeben werden muss. Meist wird fprintf() gerne benutzt um mit dem FILE-Zeiger stderr eine Meldung auf die Standartfehlerausgabe (Bildschirm) auszugeben.

Ein klassischer Fall von fprintf und fscanf ist das formatierte Einlesen einer CSV-Datei, die man mit Excel oder KSpread erzeugen oder ansehen kann. Einmal haben wir das Thema schon im Kapitel "Arrays in Excel oder KSpread einlesen".

Nehmen wir mal an wir haben folgende CSV-Log-Datei die Protokolieren soll, wer wann und wielange am System eingeloggt war.....

20:23,12.11.2001,20:50,12.11.2001,Pinguin
12:13,13.11.2001,15:29,13.11.2001,root
16:33,13.11.2001,20:23,13.11.2001,Mr.X
23:11,13.11.2001,01:12,14.11.2001,root
10:22,14.11.2001,12:14,14.11.2001,Spock
16:33,14.11.2001,20:21,14.11.2001,Scotty

Die Kommas stellen dabei die Trennzeichen da. Somit haben wir...

Uhrzeit eingeloggt, Datum, Uhrzeit ausgeloggt, Datum, User

Wir nennen diese Datei nun log.csv
Da diese CSV-Datei nicht allzuschön zu lesen ist wollen wir diese nun mit unseren neu erlernten Funktionen formatiert einlesen und auf die Standardausgabe ausgeben. Speichern sie diese Log-Datei ab. Jetzt der Quellcode dazu zum Einlesen und Ausgeben unserer Log-Datei.....

/*Download:csv.c*/
#include <stdio.h> int main(int argc, char **argv) { FILE *CSV; int login_hour, login_min; int date_day, date_mon, date_year; char name[40]; int logout_hour, logout_min; int date_dayx, date_monx, date_yearx; if(argc < 2) { fprintf(stderr, "Verwendung : %s datei.csv\n",*argv); exit(0); } CSV = fopen(argv[1], "r"); if(CSV==NULL) { perror("Fehler beim öffnen"); exit(0); } /*Nun lesen wir formatiert von der Datei ein....*/ while( (fscanf(CSV,"%d:%d,%d.%d.%d,%d:%d,%d.%d.%d,%s\n", &login_hour,&login_min,&date_day,&date_mon,&date_year, &logout_hour,&logout_min,&date_dayx,&date_monx, &date_yearx,name)) != EOF ) fprintf(stdout,"User : %s\nLogin um : %d:%d Uhr am %d.%d.%d\n" "Logout um : %d:%d Uhr am %d.%d.%d\n\n", name,login_hour,login_min,date_day,date_mon,date_year, logout_hour,logout_min,date_dayx,date_monx, date_yearx); return 0; }

Dazu muss erwähnt werden das, das Einlesen von CSV-Dateien nicht immer so einfach sein wird wie in diesem Beispiel dagestellt wird. Denn wenn die CSV-Datei zum Einlesen, komplexer wird (meist der Fall) ist erheblich mehr Aufwand zu betreiben. Ein Interesantes und sehr gutes Beispiel finden sie in dem Buch "Programmierpraxis von Brian W. Kerninghan und Rob Pike", was ich gleichzeitig auch jedem sofort empfehlen kann. Ein gutes Beispiel was sie ja mal ausprobieren können, wenn die CSV-Datei folgendermaßen aussieht.......

20:23,12.11.2001,"pinguin",20:50,12.11.2001

Versuchen sie es ruhig erst mal selbst. Hier die Möglichkeit wie wir den User pinguin ohne Gänsefüsschen auslesen können...

 char begrenzer;
 .........
 .........
 while( (fscanf(CSV,"%d:%d,%d.%d.%d,\"%[^'\"]%c,%d:%d,%d.%d.%d\n",
         &login_hour,&login_min,&date_day,&date_mon,&date_year,
         name,&begrenzer,&logout_hour,&logout_min,&date_dayx,&date_monx,
         &date_yearx)) != EOF )

Auf den ersten Blick mag dies zwar logisch sein. Aber darauf muss man erst mal kommen.

Auch sehr gut können sie fprintf einsetzen zum erstellen von dynamischen Textdateien. Ein Schelm wer dabei an CGI-Programmierung denkt. Wollen wir uns doch mal ein Beispiel ansehen wie wir dynamische Webseiten erstellen. Machen wir doch mit unserem Text2HTML-Konverter vom Kapitel zuvor weiter....

/*Download:txt2html.c*/
#include <stdio.h> void html_head(FILE *ziel) { fprintf(ziel,"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"); fprintf(ziel,"<html><head><title>Test-Webseite</title></head><body>\n"); fprintf(ziel,"<pre>\n"); fprintf(ziel,"<p style=\"margin-right:0.8cm; margin-left:0.5cm\" align=\"justify\">\n"); } void html_end(FILE *ziel) { fprintf(ziel,"</pre></p></body></html>\n"); } void sonderzeichen(int nchars, char *tag, FILE *ziel) { int i; char zeichen; for(i=0; i<nchars; i++){ zeichen=tag[i]; putc(zeichen, ziel); } } int main(int argc, char **argv) { FILE *q, *z; int zeichen; int i=0; char text[8192]; if(argc < 3) { printf("Benutzung : %s quelle ziel\n",*argv); exit(0); } q=fopen(argv[1], "r"); z=fopen(argv[2], "w"); if(q == NULL || z == NULL) { perror("Fehler"); exit(0); } /*Kopfzeile für HTML-Dokument*/ html_head(z); while((zeichen=getc(q)) != EOF){ if(zeichen=='<') sonderzeichen(4,"&lt;", z); else if(zeichen=='>') sonderzeichen(4,"&gt;", z); else if(zeichen=='\"') sonderzeichen(6,"&quot;",z); else if(zeichen=='&') sonderzeichen(5,"&amp;",z); else if(zeichen=='ä') sonderzeichen(6 ,"&auml;",z); else if(zeichen=='Ä') sonderzeichen(6 ,"&Auml;",z); else if(zeichen=='ö') sonderzeichen(6 ,"&ouml;",z); else if(zeichen=='Ö') sonderzeichen(6 ,"&Ouml;",z); else if(zeichen=='ü') sonderzeichen(6 ,"&uuml;",z); else if(zeichen=='Ü') sonderzeichen(6 ,"&Uuml;",z); else if(zeichen=='ß') sonderzeichen(6 ,"&szlig;",z); else putc(zeichen, z); } /*Ende von HTML-Datei*/ html_end(z); return 0; }

In einem späteren Kapitel finden sie einen Koverter von C-Quelltexten ins HTML-Format mit Syntaxhighlighting. Ein C2HTML - Konverter.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf