Zoeken…


Syntaxis

  • # include <stdio.h> / * Dit opnemen om een van de volgende secties te gebruiken * /
  • BESTAND * fopen (const char * pad, const char * mode); / * Open een stream in het bestand op pad met de opgegeven modus * /
  • BESTAND * freopen (const char * pad, const char * mode, FILE * stream); / * Open een bestaande stream in het bestand op pad met de opgegeven modus * /
  • int fclose (FILE * stream); / * Sluit een geopende stream * /
  • size_t fread (void * ptr, size_t size, size_t nmemb, FILE * stream); / * Lees maximaal nmemb- elementen met groottebytes elk uit de stream en schrijf ze in ptr . Retourneert het aantal gelezen elementen. * /
  • size_t fwrite (const void * ptr, size_t size, size_t nmemb, FILE * stream); / * Schrijf nmemb- elementen met groottebytes elk van ptr naar de stream . Retourneert het aantal geschreven elementen. * /
  • int fseek (FILE * stream, lange offset, int vanwaar); / * Stel de cursor van de stream in op offset , in verhouding tot de offset die wordt aangegeven door waar vandaan , en retourneert 0 als dit is gelukt. * /
  • lange ftell (FILE * stream); / * Retourneer de offset van de huidige cursorpositie vanaf het begin van de stream. * /
  • void rewind (FILE * stream); / * Zet de cursorpositie op het begin van het bestand. * /
  • int fprintf (FILE * fout, const char * fmt, ...); / * Schrijft printf-formaatstring op fout * /
  • BESTAND * stdin; / * Standaard invoerstroom * /
  • BESTAND * stdout; / * Standaard uitvoerstroom * /
  • BESTAND * stderr; / * Standaard foutstroom * /

parameters

Parameter Details
const char * modus Een tekenreeks die de openingsmodus van de door bestanden ondersteunde stream beschrijft. Zie opmerkingen voor mogelijke waarden.
waar vandaan Kan SEEK_SET om in te stellen vanaf het begin van het bestand, SEEK_END om in te stellen vanaf het einde, of SEEK_CUR om in te stellen ten opzichte van de huidige SEEK_CUR . Opmerking: SEEK_END is niet-draagbaar.

Opmerkingen

Modustekenreeksen:

freopen() in fopen() en freopen() kunnen een van deze waarden zijn:

  • "r" : open het bestand in de modus Alleen-lezen, met de cursor aan het begin van het bestand.
  • "r+" : open het bestand in de lees-schrijfmodus, met de cursor aan het begin van het bestand.
  • "w" : open of maak het bestand in de modus alleen-schrijven, met de inhoud afgekapt tot 0 bytes. De cursor staat aan het begin van het bestand.
  • "w+" : open of maak het bestand in de lees-schrijfmodus, met de inhoud afgekapt tot 0 bytes. De cursor staat aan het begin van het bestand.
  • "a" : open of maak het bestand in de modus Alleen-schrijven, met de cursor aan het einde van het bestand.
  • "a+" : open of maak het bestand in de lees-schrijfmodus, met de leescursor ingesteld op het begin van het bestand. De uitvoer wordt echter altijd aan het einde van het bestand toegevoegd.

Aan elk van deze bestandsmodi kan een b toegevoegd na de beginletter (bijvoorbeeld "rb" of "a+b" of "ab+" ). De b betekent dat het bestand moet worden behandeld als een binair bestand in plaats van een tekstbestand op die systemen waar er een verschil is. Het maakt geen verschil uit op Unix-achtige systemen; het is belangrijk op Windows-systemen. (Bovendien staat Windows fopen een expliciete t plaats van b toe om 'tekstbestand' aan te geven - en tal van andere platformspecifieke opties.)

C11
  • "wx" : maak een tekstbestand in de modus alleen-schrijven. Het bestand bestaat mogelijk niet .
  • "wbx" : maak een binair bestand in de modus alleen-schrijven. Het bestand bestaat mogelijk niet .

De x , indien aanwezig, moet het laatste teken in de modusreeks zijn.

Open en schrijf naar bestand

#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;
}

Dit programma opent het bestand met de naam die is opgegeven in het argument naar main, standaard naar output.txt als er geen argument is opgegeven. Als er al een bestand met dezelfde naam bestaat, wordt de inhoud verwijderd en wordt het bestand behandeld als een nieuw leeg bestand. Als de bestanden nog niet bestaan, wordt deze door de aanroep fopen() gemaakt.

Als de aanroep fopen() om een of andere reden mislukt, wordt een NULL waarde geretourneerd en wordt de globale waarde voor de variabele errno . Dit betekent dat het programma de geretourneerde waarde na de aanroep fopen() kan testen en perror() als fopen() mislukt.

Als de aanroep fopen() slaagt, wordt een geldige FILE aanwijzer geretourneerd. Deze aanwijzer kan vervolgens worden gebruikt om naar dit bestand te verwijzen totdat fclose() wordt aangeroepen.

De functie fputs() schrijft de gegeven tekst naar het geopende bestand en vervangt eventuele eerdere inhoud van het bestand. Net als fopen() , stelt de functie fputs() ook de errno waarde in als deze mislukt, hoewel in dit geval de functie EOF retourneert om de fout aan te geven (anders retourneert het een niet-negatieve waarde).

De functie fclose() alle buffers, sluit het bestand en maakt het geheugen vrij fclose() door FILE * . De geretourneerde waarde geeft de voltooiing aan net zoals fputs() doet (hoewel het '0' retourneert als het succesvol is), en opnieuw wordt ook de errno waarde ingesteld in het geval van een mislukking.

fprintf

U kunt fprintf op een bestand gebruiken, net zoals op een console met printf . Bijvoorbeeld om bij te houden welke speloverwinningen, verliezen en gelijkspel je zou kunnen schrijven

/* 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);
}

Een kanttekening: sommige systemen (berucht, Windows) gebruiken niet wat de meeste programmeurs "normale" regeleinden zouden noemen. Terwijl UNIX-achtige systemen \ n gebruiken om lijnen te beëindigen, gebruikt Windows een paar tekens: \ r (regelteruggave) en \ n (regelinvoer). Deze reeks wordt gewoonlijk CRLF genoemd. Wanneer u C gebruikt, hoeft u zich echter geen zorgen te maken over deze zeer platformafhankelijke details. Een AC-compiler is vereist om elke instantie van \ n te converteren naar het juiste einde van de platformregel. Dus een Windows-compiler converteert \ n naar \ r \ n, maar een UNIX-compiler houdt het zoals het is.

Voer proces uit

#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;
}

Dit programma voert een proces ( netstat ) uit via popen() en leest alle standaarduitvoer van het proces en echoot dat naar standaarduitvoer.

Opmerking: popen() bestaat niet in de standaard C-bibliotheek , maar maakt eerder deel uit van POSIX C )

Regels uit een bestand halen met getline ()

De POSIX C-bibliotheek definieert de functie getline() . Deze functie wijst een buffer toe om de inhoud van de regel vast te houden en retourneert de nieuwe regel, het aantal tekens in de regel en de grootte van de buffer.

Voorbeeldprogramma dat elke regel uit example.txt haalt:

#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;
}

Invoerbestand 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.

uitgang

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: 

In het voorbeeld wordt getline() aanvankelijk aangeroepen zonder buffer toegewezen. Tijdens deze eerste aanroep getline() een buffer toe, leest de eerste regel en plaatst de inhoud van de regel in de nieuwe buffer. Bij volgende oproepen werkt getline() dezelfde buffer bij en getline() de buffer alleen opnieuw toe als deze niet langer groot genoeg is om op de hele regel te passen. De tijdelijke buffer wordt dan vrijgegeven als we klaar zijn met het bestand.

Een andere optie is getdelim() . Dit is hetzelfde als getline() behalve dat u het regeleindeteken opgeeft. Dit is alleen nodig als het laatste teken van de regel voor uw bestandstype niet '\ n' is. getline() werkt zelfs met Windows-tekstbestanden omdat met de multibyte-regel die eindigt ( "\r\n") '\ n'` nog steeds het laatste teken op de regel is.

Voorbeeldimplementatie van 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

Open en schrijf naar een binair bestand

#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;
}

Dit programma maakt en schrijft tekst in de binaire vorm via de fwrite functie naar het bestand output.bin .

Als er al een bestand met dezelfde naam bestaat, wordt de inhoud verwijderd en wordt het bestand behandeld als een nieuw leeg bestand.

Een binaire stream is een geordende reeks tekens die interne gegevens transparant kunnen vastleggen. In deze modus worden bytes tussen het programma en het bestand geschreven zonder enige interpretatie.

Om gehele getallen draagbaar te schrijven, moet het bekend zijn of het bestandsformaat ze verwacht in groot of klein-endiaans formaat, en de grootte (meestal 16, 32 of 64 bits). Bitverschuiving en maskering kunnen vervolgens worden gebruikt om de bytes in de juiste volgorde uit te schrijven. Het is niet gegarandeerd dat gehele getallen in C twee complementaire vertegenwoordiging hebben (hoewel bijna alle implementaties dat doen). Gelukkig is er een conversie naar unsigned is gegarandeerd tweecomplement gebruiken. De code voor het schrijven van een geheel getal naar een binair bestand is daarom een beetje verrassend.

/* 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;  
}

De andere functies volgen hetzelfde patroon met kleine aanpassingen voor grootte en bytevolgorde.

fscanf ()

Laten we zeggen dat we een tekstbestand hebben en dat we alle woorden in dat bestand willen lezen om aan enkele vereisten te voldoen.

file.txt :

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

Dit is de hoofdfunctie:

#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++;
    }
}

De output zal zijn:

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()

Lees regels uit een bestand

De header stdio.h definieert de functie fgets() . Deze functie leest een regel uit een stream en slaat deze op in een opgegeven tekenreeks. De functie stopt met het lezen van tekst uit de stream wanneer een van de n - 1 tekens wordt gelezen, het newline-teken ( '\n' ) wordt gelezen of het einde van het bestand (EOF) is bereikt.

#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);
    }
}

Het programma aanroepen met een argument dat een pad is naar een bestand dat de volgende tekst bevat:

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.

Zal resulteren in de volgende uitvoer:

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]: 

Dit zeer eenvoudige voorbeeld maakt een vaste maximale lijnlengte mogelijk, zodat langere lijnen effectief als twee lijnen worden geteld. De functie fgets() vereist dat de fgets() het geheugen verschaft dat moet worden gebruikt als de bestemming voor de lijn die wordt gelezen.

POSIX maakt de functie getline() beschikbaar die in plaats daarvan intern geheugen toewijst om de buffer zo nodig te vergroten voor een lijn van elke lengte (zolang er voldoende geheugen is).



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow