Manejo de archivos en C: cómo abrir, cerrar y escribir en archivos

Si ha escrito el helloworldprograma C antes, ya conoce la E / S básica de archivos en C:

/* A simple hello world in C. */ #include  // Import IO functions. #include  int main() { // This printf is where all the file IO magic happens! // How exciting! printf("Hello, world!\n"); return EXIT_SUCCESS; }

El manejo de archivos es una de las partes más importantes de la programación. En C, usamos un puntero de estructura de un tipo de archivo para declarar un archivo:

FILE *fp;

C proporciona una serie de funciones integradas para realizar operaciones básicas de archivos:

  • fopen() - crear un nuevo archivo o abrir un archivo existente
  • fclose() - cerrar un archivo
  • getc() - lee un personaje de un archivo
  • putc() - escribe un personaje en un archivo
  • fscanf() - lee un conjunto de datos de un archivo
  • fprintf() - escribe un conjunto de datos en un archivo
  • getw() - lee un número entero de un archivo
  • putw() - escribe un número entero en un archivo
  • fseek() - establecer la posición en el punto deseado
  • ftell() - da la posición actual en el archivo
  • rewind() - establecer la posición en el punto de inicio

Abrir un archivo

La fopen()función se utiliza para crear un archivo o abrir un archivo existente:

fp = fopen(const char filename,const char mode);

Hay muchos modos para abrir un archivo:

  • r - abrir un archivo en modo lectura
  • w - abre o crea un archivo de texto en modo escritura
  • a - abre un archivo en modo anexar
  • r+ - abre un archivo en modo lectura y escritura
  • a+ - abre un archivo en modo lectura y escritura
  • w+ - abre un archivo en modo lectura y escritura

A continuación, se muestra un ejemplo de cómo leer datos de un archivo y escribir en él:

#include #include main() { FILE *fp; char ch; fp = fopen("hello.txt", "w"); printf("Enter data"); while( (ch = getchar()) != EOF) { putc(ch,fp); } fclose(fp); fp = fopen("hello.txt", "r"); while( (ch = getc(fp)! = EOF) printf("%c",ch); fclose(fp); }

Ahora podría estar pensando: "Esto solo imprime texto en la pantalla. ¿Cómo es este archivo IO?"

La respuesta no es obvia al principio y necesita algo de comprensión sobre el sistema UNIX. En un sistema UNIX, todo se trata como un archivo, lo que significa que puede leer y escribir en él.

Esto significa que su impresora se puede abstraer como un archivo, ya que todo lo que hace con una impresora es escribir con ella. También es útil pensar en estos archivos como flujos, ya que, como verá más adelante, puede redirigirlos con el shell.

Entonces, ¿cómo se relaciona esto con el helloworldarchivo IO?

Cuando llama printf, en realidad está escribiendo en un archivo especial llamado stdout, abreviatura de salida estándar . stdoutrepresenta la salida estándar según lo decidido por su shell, que generalmente es el terminal. Esto explica por qué se imprimió en su pantalla.

Hay otras dos secuencias (es decir, archivos) que están disponibles para usted con esfuerzo stdiny stderr. stdinrepresenta la entrada estándar , que su shell suele adjuntar al teclado. stderrrepresenta la salida de error estándar , que su shell generalmente adjunta al terminal.

IO de archivo rudimentario, o cómo aprendí a colocar tuberías

Suficiente teoría, ¡pongámonos manos a la obra escribiendo código! La forma más fácil de escribir en un archivo es redirigir el flujo de salida con la función de redirección de salida, >.

Si desea agregar, puede usar >>:

# This will output to the screen... ./helloworld # ...but this will write to a file! ./helloworld > hello.txt

El contenido de la hello.txtvoluntad, como era de esperar, será

Hello, world!

Digamos que tenemos otro programa llamado greet, similar a helloworld, que le da la bienvenida con un dato name:

#include  #include  int main() { // Initialize an array to hold the name. char name[20]; // Read a string and save it to name. scanf("%s", name); // Print the greeting. printf("Hello, %s!", name); return EXIT_SUCCESS; }

En lugar de leer desde el teclado, podemos redirigir stdinpara leer desde un archivo usando la <herramienta:

# Write a file containing a name. echo Kamala > name.txt # This will read the name from the file and print out the greeting to the screen. ./greet  Hello, Kamala! # If you wanted to also write the greeting to a file, you could do so using ">".

Nota: estos operadores de redireccionamiento están en bashshells similares.

El trato real

Los métodos anteriores solo funcionaron para los casos más básicos. Si quisiera hacer cosas mejores y más grandes, probablemente querrá trabajar con archivos desde C en lugar de hacerlo a través del shell.

Para lograr esto, utilizará una función llamada fopen. Esta función toma dos parámetros de cadena, el primero es el nombre del archivo y el segundo es el modo.

El modo son básicamente permisos, rpor lo que para leer, wescribir, aagregar. También puede combinarlos, lo rwque significa que podría leer y escribir en el archivo. Hay más modos, pero estos son los más utilizados.

Después de tener un FILEpuntero, puede usar básicamente los mismos comandos IO que habría usado, excepto que debe anteponerlos fy el primer argumento será el puntero del archivo. Por ejemplo, printfla versión del archivo de fprintf.

Aquí hay un programa llamado greetingsque lee un de un archivo que contiene una lista de nombres y escribe los saludos en otro archivo:

#include  #include  int main() { // Create file pointers. FILE *names = fopen("names.txt", "r"); FILE *greet = fopen("greet.txt", "w"); // Check that everything is OK. if (!names || !greet) { fprintf(stderr, "File opening failed!\n"); return EXIT_FAILURE; } // Greetings time! char name[20]; // Basically keep on reading untill there's nothing left. while (fscanf(names, "%s\n", name) > 0) { fprintf(greet, "Hello, %s!\n", name); } // When reached the end, print a message to the terminal to inform the user. if (feof(names)) { printf("Greetings are done!\n"); } return EXIT_SUCCESS; }

Supongamos que names.txtcontiene lo siguiente:

Kamala Logan Carol

Luego, después de ejecutar, greetingsel archivo greet.txtcontendrá:

Hello, Kamala! Hello, Logan! Hello, Carol!