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

 << zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch für Linux, Unix und Windows
– 2., aktualisierte und erweiterte Auflage 2006
Buch: C von A bis Z

C von A bis Z
1.116 S., mit CD, Referenzkarte, 39,90 Euro
Galileo Computing
ISBN 3-89842-643-2
gp Kapitel 18 Ein-/Ausgabe-Funktionen
  gp 18.1 Was ist eine Datei?
  gp 18.2 Formatierte und unformatierte Ein-/Ausgabe
  gp 18.3 Streams
  gp 18.4 Höhere Ein-/Ausgabe-Funktionen
  gp 18.5 Datei (Stream) öffnen – fopen
    gp 18.5.1 Modus für fopen()
    gp 18.5.2 Maximale Anzahl geöffneter Dateien – FOPEN_MAX
  gp 18.6 Zeichenweise Lesen und Schreiben – getchar und putchar
    gp 18.6.1 Ein etwas portableres getch()
  gp 18.7 Zeichenweise Lesen und Schreiben – putc/fputc und getc/fgetc
  gp 18.8 Datei (Stream) schließen – fclose
  gp 18.9 Formatiertes Einlesen/Ausgeben von Streams mit fprintf und fscanf
  gp 18.10 Standard-Streams in C
    gp 18.10.1 Standard-Streams umleiten
  gp 18.11 Fehlerbehandlung von Streams – feof, ferror und clearerr
  gp 18.12 Gelesenes Zeichen in die Eingabe zurück-schieben – ungetc
  gp 18.13 (Tastatur-)Puffer leeren – fflush
    gp 18.13.1 Pufferung
  gp 18.14 Stream positionieren – fseek, rewind und ftell
  gp 18.15 Stream positionieren – fsetpos, fgetpos
  gp 18.16 Zeilenweise Ein-/Ausgabe von Streams
    gp 18.16.1 Zeilenweise Lesen mit gets/fgets
    gp 18.16.2 Zeilenweise Schreiben mit puts/fputs
    gp 18.16.3 Zeilenweise Einlesen vom Stream mit getline() (nicht ANSI C)
    gp 18.16.4 Rezepte für zeilenweises Einlesen und Ausgeben
  gp 18.17 Blockweise Lesen und Schreiben – fread und fwrite
    gp 18.17.1 Blockweises Lesen – fread()
    gp 18.17.2 Blockweises Schreiben – fwrite()
    gp 18.17.3 Big-Endian und Little-Endian
  gp 18.18 Datei (Stream) erneut öffnen – freopen
  gp 18.19 Datei löschen oder umbenennen – remove und rename
    gp 18.19.1 remove()
    gp 18.19.2 rename()
  gp 18.20 Pufferung einstellen – setbuf und setvbuf
  gp 18.21 Temporäre Dateien erzeugen – tmpfile und tmpnam
    gp 18.21.1 mkstemp() – Sichere Alternative für Linux/UNIX (nicht ANSI C)
  gp 18.22 Fehlerausgabe mit strerror und perror
  gp 18.23 Formatiert in einem String schreiben und formatiert aus einem String lesen – sscanf und sprintf
  gp 18.24 Fortgeschrittenes Thema
  gp 18.25 Low-Level-Datei-I/O-Funktionen (nicht ANSI C)
  gp 18.26 Datei öffnen – open
  gp 18.27 Datei schließen – close
  gp 18.28 Datei erzeugen – creat
  gp 18.29 Schreiben und Lesen – write und read
  gp 18.30 File-Deskriptor positionieren – lseek
  gp 18.31 File-Deskriptor von einem Stream – fileno
  gp 18.32 Stream von File-Deskriptor – fdopen


Galileo Computing - Zum Seitenanfang

18.16 Zeilenweise Ein-/Ausgabe von Streams  downtop


Galileo Computing - Zum Seitenanfang

18.16.1 Zeilenweise Lesen mit gets/fgetdowntop

Nun folgen Funktionen zum zeilenweisen Lesen und Schreiben von einem oder in einen Stream. Zuerst die Funktionen zum Lesen:

#include <stdio.h>
char *gets(char *puffer);
char *fgets(char *puffer, int n, FILE *datei);

Mit fgets() wird zeilenweise vom Stream datei bis zum nächsten Newline-Zeichen gelesen. Die gelesene Zeile befindet sich in der Adresse von puffer mit dem Newline-Zeichen '\n' und dem abschließenden '\0'-Zeichen. Mit gets() können Sie ebenso zeilenweise einlesen, allerdings nur von der Standardeingabe (stdin). Beispielsweise:

/* gets.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
   char name[20];
   printf("Bitte geben Sie Ihren Namen ein : ");
   gets(name);  /* Gefährlich */
   printf("Hallo %s\n",name);
   return EXIT_SUCCESS;
}

Auf Linux/UNIX wird der Compiler bei diesem Programm vernünftigerweise eine Warnung ausgeben. Die Warnung, diese Funktion nicht zu verwenden, ist in Ordnung, aber vielleicht sollten gerade für Anfänger auch noch der Grund und die Alternativen bei der Fehlermeldung mit angegeben werden.

Da die Funktion gets() nicht die Anzahl der einzugebenden Zeichen überprüft, kann dies zu einem Pufferüberlauf (Buffer Overflow) führen. Deshalb sollten Sie auf keinen Fall gets(), sondern die Funktion fgets() verwenden.

Wenn Sie die Syntax von fgets() betrachten, bemerken Sie, dass sich darin außer der Zieladresse, in der die Daten eingelesen werden, zusätzlich ein Stream (FILE Zeiger) und ein Integer-Wert befinden, der die Anzahl der einzulesenden Zeichen festlegt. Mit fgets werden somit n Zeichen oder bis zum nächsten Newline ('\n') aus dem Stream in die Adresse von puffer gelesen. Wobei der Stream eine beliebig geöffnete Datei oder auch die Standardeingabe (stdin) sein kann. Hierzu das vorige Beispiel mit fgets():

/* fgets1.c */
#include <stdio.h>
#include <stdlib.h>
#define MAX 20
int main(void) {
   char name[MAX];
   printf("Bitte geben Sie Ihren Namen ein : ");
   fgets(name, MAX, stdin);
   printf("Hallo %s",name);
   return EXIT_SUCCESS;
}

Sollten hier mehr als 20 Zeichen eingegeben werden, läuft das Programm trotzdem für immer anstandslos. Es werden 20 Zeichen bzw. 18 darstellbare Zeichen + '\n' + '\0' an den String name übergeben. Ein Vorteil ist, dass mit fgets() nicht nur von stdin gelesen werden kann, sondern auch von einem beliebigen Stream. Hier ein Beispiel, wie Sie mit fgets() zeilenweise aus einer Datei lesen können:

/* fgets2.c */
#include <stdio.h>
#include <stdlib.h>
#define ZEILENLAENGE 80
int main(void) {
   FILE *quelle;
   char puffer[ZEILENLAENGE], name[20];
   printf("Welche Datei wollen Sie zum Lesen öffnen: ");
   scanf("%s",name);
   if( (quelle=fopen(name,"r")) == NULL) {
      fprintf(stderr, "Kann %s nicht oeffnen\n", name);
      return EXIT_FAILURE;
   }
   while(fgets(puffer, ZEILENLAENGE, quelle))
      fputs(puffer, stdout);
   return EXIT_SUCCESS;
}

Weil beim Einlesen vom Stream der Standardeingabe (stdin) mit fgets() auch das '\n'-Zeichen mit eingelesen wird, verwenden einige Programmierer, sei es aus Faulheit oder mangelndem Wissen, die Funktion gets(), obwohl sie wissen, dass sie diese Funktion nicht verwenden sollten. Häufig haben diese Programmierer Probleme mit dem Newline-Zeichen am Ende von Stringvergleichen, wie das folgende Beispiel zeigt:

/* fgets3.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PASSWORT "Schiller"
#define MAX 10
int main(void) {
   char pswd[MAX];
   printf("Passwort: ");
   fgets(pswd, MAX, stdin);
   if(strcmp(PASSWORT, pswd) == 0)
      printf("Willkommen\n");
   else
      printf("Passwort falsch\n");
   return EXIT_SUCCESS;
}

Auch wenn hier der Benutzer das richtige Passwort eingibt, schlägt der Stringvergleich fehl, weil fgets() das Newline-Zeichen mit einliest. Dieses Problem lässt sich mit ein paar Zeilen Code beheben:

/* fgets4.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PASSWORT "Schiller"
#define MAX 10
void chomp(char *str) {
   size_t p=strlen(str);
   /* '\n' mit '\0' überschreiben */
   str[p-1]='\0';
}
int main(void) {
   char pswd[MAX];
   printf("Passwort: ");
   fgets(pswd, MAX, stdin);
   /* ... letztes Zeichen vor \0 entfernen */
   chomp(pswd);
   if(strcmp(PASSWORT, pswd) == 0)
      printf("Willkommen\n");
   else
      printf("Passwort falsch\n");
   return EXIT_SUCCESS;
}

Die Funktion chomp() nimmt nichts anderes vor, als das letzte Zeichen vor dem Terminierungszeichen '\0' zu entfernen. Dabei wird die Anzahl der Zeichen mit der Funktion strlen() gezählt. Zieht man von diesem Wert eins ab und verwendet ihn als Indexzähler mit dem Indizierungsoperator, befinden Sie sich ein Zeichen vor '\0'.


Galileo Computing - Zum Seitenanfang

18.16.2 Zeilenweise Schreiben mit puts/fputdowntop

Mit puts() wird eine ganze Zeile auf dem Bildschirm (stdout) ausgegeben. Außerdem gibt puts() am Ende der Zeichenkette noch ein '\n'-Zeichen mit aus, die Funktion fputs() macht dies hingegen nicht. Im Gegensatz zu puts(), womit Sie nur auf die Standardausgabe (stdout) schreiben können, verwendet fputs(), wie schon fgets(), einen beliebig offenen Stream, in den geschrieben wird. Als Stream ist eine Datei zulässig, die mit einem Schreibmodus geöffnet wurde, oder auch die Standardausgabe (stdout). Hier die Syntax der beiden Funktionen:

#include <stdio.h>
int puts(const char *puffer);
int fputs(const char *puffer, FILE *datei);

Auch hierzu ein kleines Beispiel:

/* fputs.c */
#include <stdio.h>
#include <stdlib.h>
#define ZEILENLAENGE 80
int main(void) {
   FILE *quelle, *kopie;
   char puffer[ZEILENLAENGE], name[20];
   printf("Welche Datei wollen Sie zum Lesen öffnen: ");
   scanf("%s",name);
   if( (quelle=fopen(name,"r")) == NULL) {
      fprintf(stderr,"Kann %s nicht oeffnen\n",name);
      return EXIT_FAILURE;
   }
   if( (kopie=fopen("kopie.txt","w")) == NULL) {
      fprintf(stderr,"Kann kopie.txt nicht oeffnen\n");
      return EXIT_FAILURE;
   }
   while(fgets(puffer,ZEILENLAENGE,quelle)) {
      fputs(puffer, kopie);
      puts(puffer);
   }
   return EXIT_SUCCESS;
}

fputs() wird hier eingesetzt, um den Puffer, der mit fgets() ausgelesen wurde, in eine Datei namens »kopie.txt« zu schreiben. puts() hingegen gibt alles auf dem Bildschirm aus. Somit wird eine Zeile in die Datei »kopie.txt« geschrieben und dasselbe gleich nochmals auf dem Bildschirm ausgegeben.


Galileo Computing - Zum Seitenanfang

18.16.3 Zeilenweise Einlesen vom Stream mit getline() (nicht ANSI Cdowntop

Den Benutzern des GNU-gcc Compilers sei noch die Funktion getline() ans Herz gelegt. Sie gehört zwar nicht zum Umfang von ANSI C, jedoch wird in dem »The GNU C Library Reference Manual« unter www.gnu.org explizit darauf verwiesen. Warum diese Funktion so besonders ist, wird im Anschluss erläutert.

Die Funktion getline() kann als Ersatz für die E/A-Funktion fgets() verwendet werden oder noch allgemeiner – für das Einlesen einer Zeile von einem Stream. Zunächst aber die Syntax der Funktion, welche in <stdio.h> deklariert ist:

ssize_t getline (char **lineptr, size_t *n, FILE *stream)

Die Funktion liest eine Zeile inklusive dem Newline ('\n') und dem Stringende-Zeichen ('\0') in einen Puffer ein und speichert die Adresse des Puffers in *lineptr.

Bevor Sie getline() aufrufen, sollten Sie in *lineptr die Adresse eines zuvor mit malloc() allokierten Puffers der Länge *n Bytes bereitstellen.

Jetzt aber der eigentliche Clou an der Sache: Ist der übergebene Puffer groß genug, erhalten Sie in etwa den Zustand, den Sie auch mit der Funktion fgets() erreichen können. Ist dies aber nicht der Fall, verhält sich getline() nicht wie fgets() und hört bei Überschreitung der angegebenen Puffergröße einfach auf, die Zeile einzulesen. Vielmehr wird der Puffer innerhalb der Funktion auf die erforderliche Größe mit realloc() angepasst. Wenn Sie sich dieses Szenario nun noch mit der Funktion gets() vorstellen, ist das eigenständige Kürzen der einzulesenden Zeile, wie es bei fgets() geschehen würde, noch das geringere Übel.

Das war aber noch nicht alles. Wird *lineptr vor dem Aufruf mit einem NULL-Zeiger initialisiert und *n auf 0 gesetzt, übernimmt getline() die Bereitstellung des Speichers für die Zeile vollkommen selbstständig, und Sie müssen sich um nichts weiter kümmern.

Die Funktion gibt die Anzahl der eingelesenen Zeichen inklusive des Zeilen-Trennzeichens ('\n'), aber ohne das abschließende Terminierungszeichen ('\0') zurück – bei einem Fehler oder bei EOF erhalten Sie von getline() –1.

Wenn Sie getline() verwenden wollen, müssen Sie die Konstante _GNU_SOURCE vor allen include-Anweisungen definieren. Laut der GNU-Dokumentation ist diese Funktion der empfohlene Weg, Zeilen vom Stream zu lesen. Sie gilt als die sicherste ihrer Art. In diesem Zusammenhang sei aber nochmals auf das »The GNU C Library Reference Manual« verwiesen.

Hier ein einfaches Beispiel für den Fall, dass Sie die Bereitstellung des Puffers vollständig getline() überlassen wollen:

/* getline.c */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
int main(void) {
   FILE *fd;
   /* Bitte die Datei und event. den Pfad anpassen */
   char *datei = "/home/user/testdatei.txt";
   int nRet;
   size_t *t = malloc(0);
   char **gptr = (char **)malloc(sizeof(char*));
   *gptr = NULL;
   if ( (fd = fopen(datei,"r")) == NULL) {
      fprintf(stderr, "\nKonnte Datei %s nicht öffnen!", datei);
      return EXIT_FAILURE;
   }
   while( (nRet=getline(gptr, t, fd)) > 0)
      fputs(*gptr,stdout);
  return EXIT_SUCCESS;
}

Galileo Computing - Zum Seitenanfang

18.16.4 Rezepte für zeilenweises Einlesen und Ausgeben  toptop

Es folgen jetzt einige nützliche Listings, die häufig zum zeilenweisen Einlesen und Ausgeben benötigt werden. Beispiele, die auf Probleme wie die folgenden abheben:

gp  Wie kann ich die n-te Zeile auslesen?
gp  Wie kann ich von Zeile n1 bis n2 lesen?
gp  Wie kann ich alle Zeilen ausgeben, die eine bestimmte Stringfolge enthalten?
gp  Wie kann ich alle Zeilen ausgeben, die ein bestimmtes Wort enthalten?
gp  Suchen und Ersetzen in einer Textdatei (nur ganze Worte, keine Teilstrings)

Wie kann ich die n-te Zeile auslesen?

/* read_nline.c */
#include <stdio.h>
#include <stdlib.h>
#define BUF 255
char temp[BUF];
char puffer[BUF];
/* Auslesen der n-ten Zeile */
char *getsline_number(int n, FILE *file) {
   int i;
   for(i = 0; i < n-1; i++)
      if(fgets(temp, BUF, file) == NULL)
         /* Bis zur n-ten Zeile lesen */
         return NULL; /* Zeile scheint nicht zu existieren */
   /* Stream ist jetzt in der n-ten Zeile */
   if(fgets(puffer,BUF,file) == NULL)
      return NULL; /* Zeile scheint nicht zu existieren */
   return puffer; /* Zeile an Aufrufer zurück */
}
int main(int argc, char **argv) {
   FILE *f;
   unsigned int line;
   char *linenr;
   if(argc < 2) {
      fprintf(stderr, "Verwendung : %s datei\n",*argv);
      return EXIT_FAILURE;
   }
   f = fopen(argv[1],"r");
   if(f == NULL) {
      printf("Fehler beim Öffnen");
      return EXIT_FAILURE;
   }
   printf("Welche Zeile wollen Sie lesen : ");
   scanf("%d",&line);
   linenr=getsline_number(line, f);
   if(linenr == NULL) {
      fprintf(stderr, "Fehler beim Lesen der"
                      " %d-ten Zeile??\n",line);
      return EXIT_FAILURE;
    }
   printf("Zeile %d : %s\n", line, linenr);
   return EXIT_SUCCESS;
}

Wie kann ich von Zeile n1 bis n2 lesen?

/* read_line_n2n.c */
#include <stdio.h>
#include <stdlib.h>
#define BUF 255
char temp[BUF];
char puffer[BUF];
int i;  /* Zeilenzaehler */
/* Lesen von Zeile n1 bis Zeile n2 */
char *getsline_number(int n1,int n2, FILE *file) {
   for(i = 0; i < n1–1; i++)
      /* Bis zur n1-ten Zeile lesen */
      if(fgets(temp, BUF, file) == NULL)
         return NULL; /* Zeile scheint nicht zu existieren */
   /* Jetzt beginnt das eigentliche Lesen */
   printf("\n\n");
   for(i = n1; i <= n2; i++) {
      if(fgets(puffer,BUF,file) == NULL)
         /* Stream ist jetzt in der n-ten Zeile */
         return NULL;  /* Zeile scheint nicht zu existieren */
      printf("Zeile %d : %s", i, puffer);
   }
}
int main(int argc, char **argv) {
   FILE *f;
   int line1, line2;
   char *linenr;
   if(argc < 2) {
      fprintf(stderr, "Verwendung : %s datei\n", *argv);
      return EXIT_FAILURE;
   }
   f = fopen(argv[1],"r");
   if(f == NULL) {
      printf("Fehler bei fopen()...\n");
      return EXIT_FAILURE;
   }
   printf("von Zeile wollen Sie lesen : ");
   scanf("%d", &line1);
   printf("bis Zeile wollen Sie lesen : ");
   scanf("%d", &line2);
   if(line2 < line1) {
      fprintf(stderr, "bis-Zeile kann nicht "
                      "grösser sein, wie von-Zeile!\n");
      return EXIT_FAILURE;
   }
   linenr=getsline_number(line1,line2, f);
   if(linenr == NULL) {
      fprintf(stderr, "Fehler beim Lesen "
                      "der %d-ten Zeile??\n",i);
      return EXIT_FAILURE;
   }
   printf("\n");
   return EXIT_SUCCESS;
}

Wie kann ich alle Zeilen ausgeben, die eine bestimmte Stringfolge enthalten?

/* search_string.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUF 255
int main(int argc, char **argv) {
   FILE *f;
   char searchstring[BUF], puffer[BUF];
   int counter = 1;
   if(argc < 2) {
      fprintf(stderr, "Verwendung : %s datei\n", *argv);
      return EXIT_FAILURE;
   }
   f = fopen(argv[1], "r");
   if(f == NULL) {
      printf("Fehler bei fopen()... \n");
      return EXIT_FAILURE;
   }
   printf("Wonach suchen Sie in %s : ", argv[1]);
   scanf("%s", searchstring);
   printf("\n");
   while( fgets(puffer, BUF, f) != NULL ) {
      if(strstr(puffer,searchstring) != 0)
         printf("Zeile %d : %s",counter,puffer);
      counter++;
   }
   printf("\n");
   return EXIT_SUCCESS;
}

Der Nachteil an diesem Beispiel ist, dass strstr() praktisch alle Stringfolgen ausgibt. Suchen Sie beispielsweise nach der Stringfolge »int«, dann gibt strstr() auch »wahr« aus, wenn die Folge »printf«, »fprintf«, »Lint«, »Mint« … lautet. Wenn dies so gewollt ist, dann ist es in Ordnung. Falls nicht, muss mit strtok() ein Worttrenner eingebaut werden.

Wie kann ich alle Zeilen ausgeben, die ein bestimmtes Wort enthalten?

/* search_word.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF 255
/* Anpassen nach Bedarf... */
const char trennzeichen[] = ".;,:\"\' ";
int main(int argc, char **argv) {
   FILE *f;
   char searchstring[BUF];
   char puffer[BUF], puffer_bak[BUF];
   int counter=1;
   char *wort;
   if(argc < 2) {
      fprintf(stderr, "Verwendung : %s datei\n",*argv);
      return EXIT_FAILURE;
      }
   f=fopen(argv[1],"r");
   if(f == NULL) {
      printf("Fehler bei fopen()...");
      return EXIT_FAILURE;
   }
   printf("Wonach suchen Sie in %s : ",argv[1]);
   scanf("%s", searchstring);
   printf("\n");
   while(fgets(puffer, BUF, f) != NULL) {
      strcpy(puffer_bak, puffer);
      wort = strtok(puffer, trennzeichen);
      while(wort != NULL) {
         if(strcmp(wort,searchstring) == 0)
            printf("Zeile %d : %s",counter,puffer_bak);
         wort = strtok(NULL,trennzeichen);
      }
      counter++;
   }
   printf("\n");
   return EXIT_SUCCESS;
}

Suchen und Ersetzen in einer Textdatei (nur ganze Worte, keine Teilstrings)

/* search_and_replace.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define STRING_MAX 8192
int wort_begrenzer(char c) {
   return (c == ' ' || c == '\n' || c == '\t' || c == '\0' ||
       c == '.' || c == ',' || c == ';' || c == '!' ||c == '?');
}
/* Newline von fgets() entfernen */
void chomp(char *str) {
 size_t p=strlen(str);
 str[p-1] = '\0';
}
int main(int argc, char **argv) {
   FILE *file, *copy;
   char alt_string[STRING_MAX+1],neu_string[STRING_MAX+1],
        such_wort[STRING_MAX+1],replace_wort[STRING_MAX+1],
        *zgr;
   char puffer[STRING_MAX+1];
   int such_wortlen, i=0,w;
   size_t len=0;
   if(argc < 2) {
      fprintf(stderr, "Verwendung: %s datei\n", *argv);
      return EXIT_FAILURE;
   }
   file = fopen(argv[1],"r");   /* Datei zum Lesen öffnen     */
   copy = fopen(argv[1],"r+");  /* Datei zum Schreiben öffnen */
   if(file == NULL || copy == NULL) {
      printf("Fehler bei fopen()...\n");
      return EXIT_FAILURE;
   }
   alt_string[0]='\0';
   /* Kompletten String in alt_string legen ... */
   /* Bitte ggf. selbst durch dynamische Speicherverwaltung
     * genügend Platz schaffen! */
   while( (fgets(puffer,STRING_MAX+1,file)) != NULL ) {
      len += strlen(puffer)+1;
      if(len < STRING_MAX)
         strcat(alt_string, puffer);
      else {
         printf("Puffergroesse ueberschritten!\n");
         break;
      }
   }
   neu_string[0]='\0';
   printf("Welches Wort wollen Sie ersetzen : ");
   fgets(such_wort, STRING_MAX, stdin );
   chomp(such_wort);
   such_wortlen = strlen(such_wort); /* Länge des Suchwortes */
   for(w = 0; w < such_wortlen; w++)
   /* Nach Wortbegrenzern duchlaufen ... */
   if(wort_begrenzer(such_wort[w])) {
      printf("Keine Wortbegrenzer im Suchwort!!!\n");
      return EXIT_FAILURE;
   }
   printf("Durch welches Wort wollen Sie ersetzen : ");
   fgets(replace_wort, STRING_MAX, stdin);
   chomp(replace_wort);
   i = 0;
   while(1){
      if( (zgr=strstr(&alt_string[i], such_wort)) == NULL) {
         /* Kein Wort zu ersetzen */
         strcat(neu_string, &alt_string[i]);
         break;
      }
      else { /*..ansonsten von Byte i bis zgr in neu_string*/
         strncat(neu_string, &alt_string[i], zgr-&alt_string[i]);
         /* Jetzt überprüfen, ob wir ein Wort haben und
          * keinen Teilstring oder das Wort am Anfang steht */
         if( (zgr-&alt_string[0]==0 ||
              wort_begrenzer( *(zgr-1))) &&
              wort_begrenzer( *(zgr+such_wortlen))) {
            strcat(neu_string, replace_wort);
            /* Nach ersetztem Wort den Zeiger setzen ... */
            i += zgr + such_wortlen-&alt_string[i];
         }
         else {
            strncat(neu_string, zgr, 1);
            i += zgr + 1-&alt_string[i];
         }
      }
   } /* Ende while(1) */
   /* Für Testausgabe ... */
   /* printf("Neuer String : %s\n",neu_string); */
   strcpy(alt_string, neu_string);
   /* Achtung jetzt wirds ernst,
    * für Testausgabe in Kommentar setzen*/
   fputs(alt_string, copy);
   neu_string[0] = '\0';
   return EXIT_SUCCESS;
}
 << zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z
C von A bis Z
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-UNIX-Programmierung






 Linux-UNIX-Programmierung


Zum Katalog: C/C++






 C/C++


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Reguläre Ausdrücke






 Reguläre Ausdrücke


Zum Katalog: Linux






 Linux


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2006
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.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de