Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
Vorwort des Gutachters
1 Einstieg in C
2 Das erste Programm
3 Grundlagen
4 Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
5 Basisdatentypen
6 Operatoren
7 Typumwandlung
8 Kontrollstrukturen
9 Funktionen
10 Präprozessor-Direktiven
11 Arrays
12 Zeiger (Pointer)
13 Kommandozeilenargumente
14 Dynamische Speicherverwaltung
15 Strukturen
16 Ein-/Ausgabe-Funktionen
17 Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
19 Zeitroutinen
20 Weitere Headerdateien und ihre Funktionen (ANSI C)
21 Dynamische Datenstrukturen
22 Algorithmen
23 CGI mit C
24 MySQL und C
25 Netzwerkprogrammierung und Cross–Plattform-Entwicklung
26 Paralleles Rechnen
27 Sicheres Programmieren
28 Wie geht’s jetzt weiter?
A Operatoren
B Die C-Standard-Bibliothek
Stichwort

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch
Buch: C von A bis Z

C von A bis Z
3., aktualisierte und erweiterte Auflage, geb., mit CD und Referenzkarte
1.190 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1411-7
Pfeil 16 Ein-/Ausgabe-Funktionen
Pfeil 16.1 Was ist eine Datei?
Pfeil 16.2 Formatierte und unformatierte Ein-/Ausgabe
Pfeil 16.3 Standard-Streams
Pfeil 16.4 Höhere Ein-/Ausgabe-Funktionen
Pfeil 16.5 Datei (Stream) öffnen – »fopen«
Pfeil 16.5.1 Modus für »fopen()«
Pfeil 16.5.2 Maximale Anzahl geöffneter Dateien – »FOPEN_MAX«
Pfeil 16.6 Zeichenweise lesen und schreiben – »getchar()« und »putchar()«
Pfeil 16.6.1 Ein etwas portableres »getch()«
Pfeil 16.7 Zeichenweise lesen und schreiben – »putc()«/»fputc()« und »getc()«/»fgetc()«
Pfeil 16.8 Datei (Stream) schließen – »fclose()«
Pfeil 16.9 Formatiertes Einlesen/Ausgeben von Streams mit »fprintf()« und »fscanf()«
Pfeil 16.10 Standard-Streams in C
Pfeil 16.10.1 Standard-Streams umleiten
Pfeil 16.11 Fehlerbehandlung von Streams – »feof()«, »ferror()« und »clearerr()«
Pfeil 16.12 Gelesenes Zeichen in die Eingabe zurückschieben – »ungetc()«
Pfeil 16.13 (Tastatur-)Puffer leeren – »fflush()«
Pfeil 16.14 Stream positionieren – »fseek()«, »rewind()« und »ftell()«
Pfeil 16.15 Stream positionieren – »fsetpos()«, »fgetpos()«
Pfeil 16.16 Zeilenweise Ein-/Ausgabe von Streams
Pfeil 16.16.1 Zeilenweise lesen mit »gets()«/»fgets()«
Pfeil 16.16.2 Zeilenweise schreiben mit »puts()«/»fputs()«
Pfeil 16.16.3 Zeilenweise vom Stream einlesen mit »getline()« (nicht ANSI C)
Pfeil 16.16.4 Rezepte für zeilenweises Einlesen und Ausgeben
Pfeil 16.17 Blockweise lesen und schreiben – »fread()« und »fwrite()«
Pfeil 16.17.1 Blockweise lesen – »fread()«
Pfeil 16.17.2 Blockweise schreiben – »fwrite()«
Pfeil 16.17.3 Big Endian und Little Endian
Pfeil 16.18 Datei (Stream) erneut öffnen – »freopen()«
Pfeil 16.19 Datei löschen oder umbenennen – »remove()« und »rename()«
Pfeil 16.19.1 remove()
Pfeil 16.19.2 rename()
Pfeil 16.20 Pufferung einstellen – »setbuf()« und »setvbuf()«
Pfeil 16.20.1 Die Funktion »setbuf()«
Pfeil 16.20.2 Die Funktion »setvbuf()«
Pfeil 16.21 Temporäre Dateien erzeugen – »tmpfile()« und »tmpnam()«
Pfeil 16.21.1 »mkstemp()« – sichere Alternative für Linux/UNIX (nicht ANSI C)
Pfeil 16.22 Fehlerbehandlung
Pfeil 16.22.1 Fehlerausgabe mit »perror()«
Pfeil 16.22.2 Fehlerausgabe mit »strerror()«
Pfeil 16.23 Formatiert in einen String schreiben und formatiert aus einem String lesen – »sscanf()« und »sprintf()«
Pfeil 16.24 Byte- und wide-orientierter Stream
Pfeil 16.25 Ein fortgeschrittenes Thema
Pfeil 16.26 Low-Level-Datei-I/O-Funktionen (nicht ANSI C)
Pfeil 16.26.1 Datei öffnen – »open()«
Pfeil 16.26.2 Datei schließen – »close()«
Pfeil 16.26.3 Datei erzeugen – »creat()«
Pfeil 16.26.4 Schreiben und Lesen – »write()« und »read()«
Pfeil 16.26.5 File-Deskriptor positionieren – »lseek()«
Pfeil 16.26.6 File-Deskriptor von einem Stream – »fileno()«
Pfeil 16.26.7 Stream von File-Deskriptor – »fdopen()«


Rheinwerk Computing - Zum Seitenanfang

16.9 Formatiertes Einlesen/Ausgeben von Streams mit »fprintf()« und »fscanf()« topZur vorigen Überschrift

fprintf() und fscanf() sind die dateiorientierten Gegenstücke zu den Funktionen printf() und scanf(). Ihre Syntax sieht so aus:

#include <stdio.h>

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

Natürlich würde mit

fscanf(stdin, "%d", &x);
fprintf(stdout, "Hallo Welt\n");

dasselbe erreicht wie mit:

scanf("%d", &x);
printf("Hallo Welt\n");

Beide Schreibweisen lesen bzw. schreiben formatiert auf die Streams stdin bzw. stdout. fprintf() werden gern benutzt, um durch den Stream stderr eine Meldung auf die Standardfehlerausgabe (Bildschirm) ungepuffert auszugeben.


Hinweis

Das Argument format ist ein Formatstring, den Sie bereits in Abschnitt 4.2, »Formatierte Ausgabe mit ›printf()‹«, näher kennengelernt haben. Die entsprechenden Umwandlungsvorgaben dazu habe ich in Abschnitt 5.20 behandelt.


Ein klassischer Fall von fprintf() und fscanf() ist das formatierte Einlesen einer CSV-Datei, die Sie mit Tabellenkalkulationsprogrammen erzeugen und ansehen können. Das Thema wurde in Kapitel 11, »Arrays«, bereits einmal erwähnt.

Folgende CSV-Logdatei soll protokolliert werden. Darin steht, wer wann und wie lange 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 Trennzeichen dar. Folgende Variablen werden benötigt:

Uhrzeit eingeloggt, Datum, Uhrzeit ausgeloggt, Datum, User

Der Name dieser Datei sei log.csv. Um diese Datei auszulesen, sollen die beiden Funktionen fprintf() und fscanf() eingesetzt werden. Hier sehen Sie den Quellcode zum Einlesen und Ausgeben der Logdatei:

/* csv_log.c */
#include <stdio.h>
#include <stdlib.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);
      return EXIT_FAILURE;
   }
   CSV = fopen(argv[1], "r");
   if(NULL == CSV) {
      fprintf(stderr, "Fehler beim Oeffnen ...\n");
      return EXIT_FAILURE;
   }

   /* Nun lesen Sie 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 EXIT_SUCCESS;
}

Meistens lässt sich das Einlesen solcher Dateien allerdings nicht so leicht realisieren wie hier dargestellt. Folgendes Beispiel ist schon wesentlich komplexer:

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

Versuchen Sie es zunächst ruhig selbst, diese Zeile mit fscanf() einzulesen. Das Problem liegt in diesem Beispiel beim String pinguin und den doppelten Hochkommata. Hier folgt die Möglichkeit, wie der User pinguin ohne Gänsefüßchen ausgelesen wird:

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 einmal kommen. Zwar ist dieser Ansatz, CSV-Dateien einzulesen, schon recht praktisch, doch er ist vollkommen inflexibel. Das Programm liest nur CSV-Dateien aus, deren Anordnung Sie kennen. Das würde heißen, für jede CSV-Datei müssten Sie den Code ändern, damit dieser wie eine Schablone in seine Form passt.

Gut eignet sich auch fprintf() zum Erstellen von dynamischen Textdateien. Hierzu ein Beispiel, wie Sie dynamisch Webseiten erstellen können. Dafür wird zuvor einfach der Text2HTML-Konverter aus Abschnitt 16.7 erweitert:

/* txt2html.c */
#include <stdio.h>
#include <stdlib.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;

   if(argc < 3) {
      printf("Benutzung : %s quelle ziel\n",*argv);
      return EXIT_FAILURE;
   }

   q = fopen(argv[1], "r");
   z = fopen(argv[2], "w");

   if(q == NULL || z == NULL) {
      printf("Fehler bei fopen() ... ");
      return EXIT_SUCCESS;
   }
   /* 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 if(zeichen=='\n') /* Zeilenumbruch */
         sonderzeichen(4, "<br>", z);
      else if(zeichen==' ')  /* Leerzeichen */
         sonderzeichen(6, "&nbsp;", z);
      else
         putc(zeichen, z);
   }
   /* Ende von HTML-Datei */
   html_end(z);
   return EXIT_SUCCESS;
}

Geben Sie nun in der Kommandozeile Folgendes ein (der Programmname sei t2html):

t2html myfile.txt myfile.hmtl

Jetzt finden Sie im Verzeichnis eine HTML-Datei namens myfile.html, die aus der Datei myfile.txt mit dem Programm t2html erzeugt wurde. Diese HTML-Datei können Sie nun mit Ihrem Lieblingsbrowser öffnen und ansehen.



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: C von A bis Z

 C von A bis Z
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: C/C++






 C/C++


Zum Rheinwerk-Shop: Einstieg in C






 Einstieg in C


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: C++ Handbuch






 C++ Handbuch


Zum Rheinwerk-Shop: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern