Suche…


Syntax

  • #include <stdio.h> / * Fügen Sie dies ein, um einen der folgenden Abschnitte zu verwenden * /
  • FILE * fopen (const char * pfad, const char * -Modus); / * Öffne einen Stream in der Datei unter Pfad mit dem angegebenen Modus * /
  • FILE * freopen (const char * pfad, const char * Modus, FILE * stream); / * Einen vorhandenen Stream in der Datei unter Pfad im angegebenen Modus erneut öffnen. * /
  • int fclose (FILE * stream); / * Einen geöffneten Stream schließen * /
  • size_t fread (void * ptr, size_t size, size_t nmemb, FILE * stream); / * Höchstens nmemb Elemente der Größe Lesen jeder aus dem Stream - Bytes und schreibt sie in PTR. Gibt die Anzahl der gelesenen Elemente zurück. * /
  • size_t fwrite (const void * ptr, size_t size, size_t nmemb, FILE * stream); / * Schreibe nmemb Elemente size Bytes jeweils von PTR in den Stream. Gibt die Anzahl der geschriebenen Elemente zurück. * /
  • int fseek (FILE * stream, langer Offset, int woce); / * Der Cursor des Stroms Stellen zu kompensieren, bezogen auf die von woher gesagt Offset und liefert 0 , wenn es erfolgreich war. * /
  • long ftell (FILE * stream); / * Gibt den Offset der aktuellen Cursorposition vom Anfang des Streams zurück. * /
  • Zurückspulen (FILE * stream); / * Setzt die Cursorposition auf den Anfang der Datei. * /
  • int fprintf (FILE * fout, const char * fmt, ...); / * Schreibt den printf-Formatstring in fout * /
  • FILE * stdin; / * Standardeingangsstrom * /
  • FILE * stdout; / * Standardausgabestrom * /
  • FILE * stderr; / * Standardfehlerstrom * /

Parameter

Parameter Einzelheiten
const char * Modus Eine Zeichenfolge, die den Eröffnungsmodus des durch Dateien gesicherten Streams beschreibt. Siehe Anmerkungen zu möglichen Werten.
int woher SEEK_SET vom Anfang der Datei aus gesetzt werden, SEEK_END vom Ende der Datei oder SEEK_CUR , um den aktuellen SEEK_CUR . Hinweis: SEEK_END ist nicht portierbar.

Bemerkungen

Moduszeichenfolgen:

fopen() in fopen() und freopen() können einen dieser Werte freopen() :

  • "r" : Öffnet die Datei im Nur-Lese-Modus, wobei der Cursor auf den Anfang der Datei gesetzt ist.
  • "r+" : Öffnet die Datei im Lese- und Schreibmodus, wobei der Cursor auf den Anfang der Datei gesetzt ist.
  • "w" : Öffnen oder erstellen Sie die Datei im schreibgeschützten Modus, wobei der Inhalt auf 0 Byte gekürzt wird. Der Cursor steht auf den Anfang der Datei.
  • "w+" : Öffnen oder erstellen Sie die Datei im Lese- / Schreibmodus, wobei der Inhalt auf 0 Byte gekürzt wird. Der Cursor steht auf den Anfang der Datei.
  • "a" : Öffnen oder erstellen Sie die Datei im schreibgeschützten Modus, wobei sich der Cursor am Ende der Datei befindet.
  • "a+" : Öffnen oder erstellen Sie die Datei im Lese- / Schreibmodus, wobei der Lese-Cursor am Anfang der Datei steht. Die Ausgabe wird jedoch immer an das Ende der Datei angehängt.

Für jeden dieser Dateimodi kann nach dem Anfangsbuchstaben ein b hinzugefügt werden (z. B. "rb" oder "a+b" oder "ab+" ). Das b bedeutet, dass die Datei auf den Systemen, in denen ein Unterschied besteht, anstelle von Textdateien als Binärdateien behandelt werden sollte. Auf Unix-ähnlichen Systemen macht es keinen Unterschied. es ist wichtig auf Windows-Systemen. (Außerdem erlaubt Windows fopen ein explizites t anstelle von b , um "Textdatei" anzugeben - und zahlreiche andere plattformspezifische Optionen.)

C11
  • "wx" : Erstellen Sie eine Textdatei im schreibgeschützten Modus. Die Datei existiert möglicherweise nicht .
  • "wbx" : "wbx" eine Binärdatei im schreibgeschützten Modus. Die Datei existiert möglicherweise nicht .

Das x , falls vorhanden, das letzte Zeichen in der Moduszeichenfolge sein.

Öffnen Sie und schreiben Sie in die Datei

#include <stdio.h>   /* for perror(), fopen(), fputs() and fclose() */
#include <stdlib.h>  /* for the EXIT_* macros */
 
int main(int argc, char **argv)
{
    int e = EXIT_SUCCESS;

    /* Get path from argument to main else default to output.txt */
    char *path = (argc > 1) ? argv[1] : "output.txt";

    /* Open file for writing and obtain file pointer */
    FILE *file = fopen(path, "w");
    
    /* Print error message and exit if fopen() failed */
    if (!file) 
    {
        perror(path);
        return EXIT_FAILURE;
    }

    /* Writes text to file. Unlike puts(), fputs() does not add a new-line. */
    if (fputs("Output in file.\n", file) == EOF)
    {
        perror(path);
        e = EXIT_FAILURE;
    }

    /* Close file */
    if (fclose(file)) 
    {
        perror(path);
        return EXIT_FAILURE;
    }
    return e;
}

Dieses Programm öffnet die Datei mit dem Namen, der im Argument angegeben ist, in main, wobei output.txt wenn kein Argument angegeben wird. Wenn bereits eine Datei mit demselben Namen vorhanden ist, wird deren Inhalt verworfen und die Datei wird als neue leere Datei behandelt. Wenn die Dateien noch nicht vorhanden sind, werden sie vom fopen() Aufruf erstellt.

Wenn der Aufruf von fopen() aus irgendeinem Grund fehlschlägt, gibt er einen NULL Wert zurück und legt den globalen Wert der errno Variablen fest. Dies bedeutet , dass das Programm den Rückgabewert nach dem Test kann fopen() Aufruf und Nutzung perror() , wenn fopen() fehlschlägt.

Wenn der Aufruf von fopen() erfolgreich ist, wird ein gültiger FILE Zeiger zurückgegeben. Dieser Zeiger kann dann verwendet werden, um auf diese Datei zu verweisen, bis fclose() für sie aufgerufen wird.

Die Funktion fputs() schreibt den angegebenen Text in die geöffnete Datei und ersetzt den vorherigen Inhalt der Datei. Ähnlich wie bei fopen() setzt die Funktion fputs() auch den errno Wert, falls dieser fehlschlägt. In diesem Fall gibt die Funktion EOF , um den Fehler anzuzeigen (andernfalls einen nicht negativen Wert).

Die Funktion fclose() alle Puffer, schließt die Datei und gibt den Speicher frei, auf den FILE * . Der Rückgabewert gibt die Fertigstellung genau wie bei fputs() (obwohl bei Erfolg '0' zurückgegeben wird). Im errno wird auch der errno Wert gesetzt.

fprintf

Sie können fprintf für eine Datei genauso wie für eine Konsole mit printf . Zum Beispiel, um die Gewinne, Verluste und Bindungen, die Sie schreiben, im Auge zu behalten

/* saves wins, losses and, ties */
void savewlt(FILE *fout, int wins, int losses, int ties)
{
    fprintf(fout, "Wins: %d\nTies: %d\nLosses: %d\n", wins, ties, losses);
}

Eine Randnotiz: Einige Systeme (infamous, Windows) verwenden nicht das, was die meisten Programmierer als "normale" Leitungsenden bezeichnen würden. Während UNIX-ähnliche Systeme \ n verwenden, um Zeilen zu beenden, verwendet Windows ein Zeichenpaar: \ r (Wagenrücklauf) und \ n (Zeilenvorschub). Diese Sequenz wird allgemein als CRLF bezeichnet. Bei der Verwendung von C müssen Sie sich jedoch nicht um diese stark plattformabhängigen Details kümmern. Ein AC-Compiler ist erforderlich, um jede Instanz von \ n in die korrekte Endung der Plattformzeile zu konvertieren. Ein Windows-Compiler würde also \ n in \ r \ n konvertieren, aber ein UNIX-Compiler würde es beibehalten.

Prozess ausführen

#include <stdio.h>

void print_all(FILE *stream)
{
    int c;
    while ((c = getc(stream)) != EOF)
        putchar(c);
}
int main(void)
{
    FILE *stream;

    /* call netstat command. netstat is available for Windows and Linux */
    if ((stream = popen("netstat", "r")) == NULL)
        return 1;
  
    print_all(stream);
    pclose(stream);
    return 0;
}

Dieses Programm führt einen Prozess ( netstat ) über popen() und liest alle Standardausgaben aus dem Prozess und gibt diese an die Standardausgabe zurück.

Hinweis: popen() ist nicht in der Standard-C-Bibliothek vorhanden , sondern ist ein Teil von POSIX C ).

Zeilen mit getline () aus einer Datei holen

Die POSIX C-Bibliothek definiert die Funktion getline() . Diese Funktion weist einen Puffer für den Zeileninhalt zu und gibt die neue Zeile, die Anzahl der Zeichen in der Zeile und die Größe des Puffers zurück.

Beispielprogramm, das jede Zeile aus example.txt :

#include <stdlib.h>
#include <stdio.h>  


#define FILENAME "example.txt"

int main(void)
{
  /* Open the file for reading */
  char *line_buf = NULL;
  size_t line_buf_size = 0;
  int line_count = 0;
  ssize_t line_size;
  FILE *fp = fopen(FILENAME, "r");
  if (!fp)
  {
    fprintf(stderr, "Error opening file '%s'\n", FILENAME);
    return EXIT_FAILURE;
  }

  /* Get the first line of the file. */
  line_size = getline(&line_buf, &line_buf_size, fp);

  /* Loop through until we are done with the file. */
  while (line_size >= 0)
  {
    /* Increment our line count */
    line_count++;

    /* Show the line details */
    printf("line[%06d]: chars=%06zd, buf size=%06zu, contents: %s", line_count,
        line_size, line_buf_size, line_buf);

    /* Get the next line */
    line_size = getline(&line_buf, &line_buf_size, fp);
  }

  /* Free the allocated line buffer */
  free(line_buf);
  line_buf = NULL;

  /* Close the file now that we are done with it */
  fclose(fp);

  return EXIT_SUCCESS;
}

Eingabedatei example.txt

This is a file
  which has
multiple lines
    with various indentation,
blank lines



a really long line to show that getline() will reallocate the line buffer if the length of a line is too long to fit in the buffer it has been given,
  and punctuation at the end of the lines.

Ausgabe

line[000001]: chars=000015, buf size=000016, contents: This is a file
line[000002]: chars=000012, buf size=000016, contents:   which has
line[000003]: chars=000015, buf size=000016, contents: multiple lines
line[000004]: chars=000030, buf size=000032, contents:     with various indentation,
line[000005]: chars=000012, buf size=000032, contents: blank lines
line[000006]: chars=000001, buf size=000032, contents: 
line[000007]: chars=000001, buf size=000032, contents: 
line[000008]: chars=000001, buf size=000032, contents: 
line[000009]: chars=000150, buf size=000160, contents: a really long line to show that getline() will reallocate the line buffer if the length of a line is too long to fit in the buffer it has been given,
line[000010]: chars=000042, buf size=000160, contents:  and punctuation at the end of the lines.
line[000011]: chars=000001, buf size=000160, contents: 

Im Beispiel wird getline() zunächst ohne zugewiesenen Puffer aufgerufen. Während dieses ersten Aufrufs weist getline() einen Puffer zu, liest die erste Zeile und platziert den Inhalt der Zeile im neuen Puffer. Bei nachfolgenden Aufrufen aktualisiert getline() denselben Puffer und getline() den Puffer nur dann neu zu, wenn er nicht mehr groß genug ist, um in die gesamte Zeile zu passen. Der temporäre Puffer wird dann freigegeben, wenn die Datei fertig ist.

Eine weitere Option ist getdelim() . Dies ist dasselbe wie getline() außer dass Sie das Zeilenendezeichen angeben. Dies ist nur erforderlich, wenn das letzte Zeichen der Zeile für Ihren Dateityp nicht '\ n' ist. getline() funktioniert auch mit Windows-Textdateien, da mit der Multibyte-Zeilenendung ( "\r\n") '\ n'` noch das letzte Zeichen der Zeile ist.

Beispielimplementierung von getline()

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>


#if !(defined _POSIX_C_SOURCE)
typedef long int ssize_t;
#endif

/* Only include our version of getline() if the POSIX version isn't available. */

#if !(defined _POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L

#if !(defined SSIZE_MAX)
#define SSIZE_MAX (SIZE_MAX >> 1)
#endif

ssize_t getline(char **pline_buf, size_t *pn, FILE *fin)
{
  const size_t INITALLOC = 16;
  const size_t ALLOCSTEP = 16;
  size_t num_read = 0;

  /* First check that none of our input pointers are NULL. */
  if ((NULL == pline_buf) || (NULL == pn) || (NULL == fin))
  {
    errno = EINVAL;
    return -1;
  }

  /* If output buffer is NULL, then allocate a buffer. */
  if (NULL == *pline_buf)
  {
    *pline_buf = malloc(INITALLOC);
    if (NULL == *pline_buf)
    {
      /* Can't allocate memory. */
      return -1;
    }
    else
    {
      /* Note how big the buffer is at this time. */
      *pn = INITALLOC;
    }
  }

  /* Step through the file, pulling characters until either a newline or EOF. */

  {
    int c;
    while (EOF != (c = getc(fin)))
    {
      /* Note we read a character. */
      num_read++;

      /* Reallocate the buffer if we need more room */
      if (num_read >= *pn)
      {
        size_t n_realloc = *pn + ALLOCSTEP;
        char * tmp = realloc(*pline_buf, n_realloc + 1); /* +1 for the trailing NUL. */
        if (NULL != tmp)
        {
          /* Use the new buffer and note the new buffer size. */
          *pline_buf = tmp;
          *pn = n_realloc;
        }
        else
        {
          /* Exit with error and let the caller free the buffer. */
          return -1;
        }

        /* Test for overflow. */
        if (SSIZE_MAX < *pn)
        {
          errno = ERANGE;
          return -1;
        }
      }

      /* Add the character to the buffer. */
      (*pline_buf)[num_read - 1] = (char) c;

      /* Break from the loop if we hit the ending character. */
      if (c == '\n')
      {
        break;
      }
    }

    /* Note if we hit EOF. */
    if (EOF == c)
    {
      errno = 0;
      return -1;
    }
  }

  /* Terminate the string by suffixing NUL. */
  (*pline_buf)[num_read] = '\0';

  return (ssize_t) num_read;
}

#endif

Öffnen und schreiben Sie in eine Binärdatei

#include <stdlib.h>
#include <stdio.h>


int main(void)
{
   result = EXIT_SUCCESS;

   char file_name[] = "outbut.bin";
   char str[] = "This is a binary file example";
   FILE * fp = fopen(file_name, "wb");
   
   if (fp == NULL)  /* If an error occurs during the file creation */
   {
     result = EXIT_FAILURE;
     fprintf(stderr, "fopen() failed for '%s'\n", file_name);
   }
   else
   {
     size_t element_size = sizeof *str;
     size_t elements_to_write = sizeof str;

     /* Writes str (_including_ the NUL-terminator) to the binary file. */
     size_t elements_written = fwrite(str, element_size, elements_to_write, fp); 
     if (elements_written != elements_to_write)
     {
       result = EXIT_FAILURE;
       /* This works for >=c99 only, else the z length modifier is unknown. */
       fprintf(stderr, "fwrite() failed: wrote only %zu out of %zu elements.\n", 
         elements_written, elements_to_write);
       /* Use this for <c99: *
       fprintf(stderr, "fwrite() failed: wrote only %lu out of %lu elements.\n", 
         (unsigned long) elements_written, (unsigned long) elements_to_write);
        */
     }

     fclose(fp);
   }

   return result;
}

Dieses Programm erstellt und schreibt Text in binärer Form über die Funktion fwrite in die Datei output.bin .

Wenn bereits eine Datei mit demselben Namen vorhanden ist, wird deren Inhalt verworfen und die Datei wird als neue leere Datei behandelt.

Ein binärer Stream ist eine geordnete Folge von Zeichen, die interne Daten transparent aufzeichnen kann. In diesem Modus werden Bytes ohne Interpretation zwischen dem Programm und der Datei geschrieben.

Um Ganzzahlen portabel schreiben zu können, muss bekannt sein, ob das Dateiformat sie im Big- oder Little-Endian-Format und in der Größe (normalerweise 16, 32 oder 64 Bit) erwartet. Bitverschiebung und Maskierung können dann zum Schreiben der Bytes in der richtigen Reihenfolge verwendet werden. Für Ganzzahlen in C ist nicht garantiert, dass sie eine Zweierkomplementdarstellung haben (obwohl dies bei fast allen Implementierungen der Fall ist). Zum Glück einer Umwandlung in unsigned garantiert Zweier - Komplement zu verwenden. Der Code zum Schreiben einer vorzeichenbehafteten Ganzzahl in eine Binärdatei ist daher etwas überraschend.

/* write a 16-bit little endian integer */
int fput16le(int x, FILE *fp)
{
    unsigned int rep = x;
    int e1, e2;

    e1 = fputc(rep & 0xFF, fp);
    e2 = fputc((rep >> 8) & 0xFF, fp);

    if(e1 == EOF || e2 == EOF)
        return EOF;
    return 0;  
}

Die anderen Funktionen folgen dem gleichen Muster mit geringfügigen Änderungen für Größe und Byte-Reihenfolge.

fscanf ()

Nehmen wir an, wir haben eine Textdatei und möchten alle Wörter in dieser Datei lesen, um einige Anforderungen zu erfüllen.

Datei.txt :

This is just
a test file
to be used by fscanf()

Dies ist die Hauptfunktion:

#include <stdlib.h>
#include <stdio.h>

void printAllWords(FILE *);

int main(void)
{
  FILE *fp;

  if ((fp = fopen("file.txt", "r")) == NULL) {
      perror("Error opening file");
      exit(EXIT_FAILURE);
  }

  printAllWords(fp);

  fclose(fp);
  
  return EXIT_SUCCESS;
}

void printAllWords(FILE * fp)
{
    char tmp[20];
    int i = 1;

    while (fscanf(fp, "%19s", tmp) != EOF) {
        printf("Word %d: %s\n", i, tmp);
        i++;
    }
}

Die Ausgabe wird sein:

Word 1: This 
Word 2: is 
Word 3: just
Word 4: a 
Word 5: test
Word 6: file
Word 7: to
Word 8: be 
Word 9: used
Word 10: by
Word 11: fscanf()

Zeilen aus einer Datei lesen

Der Header stdio.h definiert die Funktion fgets() . Diese Funktion liest eine Zeile aus einem Stream und speichert sie in einer angegebenen Zeichenfolge. Die Funktion beendet das Lesen von Text aus dem Stream, wenn entweder n - 1 Zeichen gelesen werden, das Zeilenvorschubzeichen ( '\n' ) gelesen wird oder das Dateiende (EOF) erreicht wird.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LINE_LENGTH 80

int main(int argc, char **argv)
{
    char *path;
    char line[MAX_LINE_LENGTH] = {0};
    unsigned int line_count = 0;
    
    if (argc < 1)
        return EXIT_FAILURE;
    path = argv[1];
    
    /* Open file */
    FILE *file = fopen(path, "r");
    
    if (!file)
    {
        perror(path);
        return EXIT_FAILURE;
    }
    
    /* Get each line until there are none left */
    while (fgets(line, MAX_LINE_LENGTH, file))
    {
        /* Print each line */
        printf("line[%06d]: %s", ++line_count, line);
        
        /* Add a trailing newline to lines that don't already have one */
        if (line[strlen(line) - 1] != '\n')
            printf("\n");
    }
    
    /* Close file */
    if (fclose(file))
    {
        return EXIT_FAILURE;
        perror(path);
    }
}

Aufruf des Programms mit einem Argument, bei dem es sich um einen Pfad zu einer Datei handelt, die den folgenden Text enthält:

This is a file
  which has
multiple lines
    with various indentation,
blank lines



a really long line to show that the line will be counted as two lines if the length of a line is too long to fit in the buffer it has been given,
  and punctuation at the end of the lines.

Ergibt folgende Ausgabe:

line[000001]: This is a file
line[000002]:   which has
line[000003]: multiple lines
line[000004]:     with various indentation,
line[000005]: blank lines
line[000006]: 
line[000007]: 
line[000008]: 
line[000009]: a really long line to show that the line will be counted as two lines if the le
line[000010]: ngth of a line is too long to fit in the buffer it has been given,
line[000011]:  and punctuation at the end of the lines.
line[000012]: 

Dieses sehr einfache Beispiel erlaubt eine feste maximale Zeilenlänge, so dass längere Zeilen effektiv als zwei Zeilen gezählt werden. Die Funktion fgets() setzt fgets() , dass der aufrufende Code den Speicher bereitstellt, der als Ziel für die gelesene Zeile verwendet werden soll.

POSIX stellt die Funktion getline() Verfügung, die stattdessen intern Speicher getline() , um den Puffer nach Bedarf für eine Zeile beliebiger Länge zu vergrößern (sofern ausreichend Speicher vorhanden ist).



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow