|
![ein Kapitel weiter](../weiter.gif)
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,"<", z);
else if(zeichen=='>')
sonderzeichen(4,">", z);
else if(zeichen=='\"')
sonderzeichen(6,""",z);
else if(zeichen=='&')
sonderzeichen(5,"&",z);
else if(zeichen=='ä')
sonderzeichen(6 ,"ä",z);
else if(zeichen=='Ä')
sonderzeichen(6 ,"Ä",z);
else if(zeichen=='ö')
sonderzeichen(6 ,"ö",z);
else if(zeichen=='Ö')
sonderzeichen(6 ,"Ö",z);
else if(zeichen=='ü')
sonderzeichen(6 ,"ü",z);
else if(zeichen=='Ü')
sonderzeichen(6 ,"Ü",z);
else if(zeichen=='ß')
sonderzeichen(6 ,"ß",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 weiter](../weiter.gif)
© 2001,2002 Jürgen Wolf
|