Lenguaje C: Entrada y salida


E/S estándar

Las entradas y salidas de información de un programa pueden realizarse:

Cuando un programa está en ejecución, se convierte en un proceso que dispone de:

El estándar ANSI C creó un conjunto de funciones estándar para la entrada y salida a través de los ficheros estándar stdin y stdout

   #include <stdio.h>

Las más importantes son:

Salida con formato: printf()

La función devuelve el número de bytes escritos o EOF en caso de error

   printf("cadena_de_control", lista_de_argumentos);
\a Alarma (pitido)\'Comilla simple
\b Espacio atrás \“ Comillas dobles
\f Salto de página\\ Barra invertida
\n Nueva línea \oo Carácter ASCII en octal
\r Retorno de línea\xHH Carácter ASCII en hexadecimal
\t Tabulador\0 Carácter nulo (Código ASCII cero)
   %[flags][anchura][.precision][prefijo-tipo] formato
   printf("Número entero: %d", edad);
   printf("Letra:%c t Octal:%o t Hexadecimal: %x",codigo, codigo, codigo);
   printf("Número real: %f t %E t %G", estatura, estatura, estatura);
Entrada con formato: scanf()

La función devuelve el número de datos leídos correctamente o EOF en caso de error

   scanf("cadena_de_control", lista_de_argumentos);
   %[*][anchura][prefijo-tipo] formato
   scanf("%d %*s”, &valor); /* Lee el dato y la cadena que se teclee a continuación del valor entero,
                               pero no se asigna a ninguna variable */

El buffer de teclado es una zona de almacenamiento intermedio asociada a la entrada estándar stdin

   fflush(sdtin);
Entrada de caracteres: getchar()

Función para leer caracteres del teclado. Prototipo:

   int getchar(void);
   char a;
   a = getchar(void);
   scanf("%c", &a);
Salida de caracteres: putchar()

Función para mostrar caracteres en la pantalla. Prototipo:

   int putchar(int variable);
   char a;
   putchar((int)a);
   printf("%c", a);

Lectura y escritura de cadenas

En lenguaje C no existe un tipo de dato de cadena de caracteres, los arrays de caracteres o cadenas de caracteres son vectores:

   cadena[indice]
   char nombrevariable[NUMERO_DE_ELEMENTOS];
Lectura de cadenas: gets( )
   gets(char *cadena);
   #define NUM_ELEM 100
   char cadena[NUM_ELEM];  /* Declaración */
   gets(cadena);          /* Lee una cadena */
   scanf("%s", cadena);    /* Lee una cadena */
Escritura de cadenas: puts( )
   puts(cadena);
   puts(cadena)           /* Muestra una cadena */
   printf("%s", cadena);   /* Muestra una cadena */

Ficheros y secuencias

El lenguaje C proporciona mecanismos para la entrada y salida por ficheros:

En modo texto el final de la línea se representa:

   En un lugar de la mancha,
   de cuyo nombre no quiero acordarme.
   En un lugar de la mancha, r\nde cuyo nombre no quiero acordarme.EOF
   En un lugar de la mancha, nde cuyo nombre no quiero acordarme.EOF

Al ejecutar un programa en modo consola, automáticamente el sistema operativo abre tres secuencias estándar:

Apertura y cierre de un fichero

Para acceder a los ficheros se precisa un descriptor del fichero (puntero de tipo FILE)

   FILE *puntero;

Antes de cualquier operación sobre un fichero es preciso abrir el fichero, utilizando la función fopen()

   FILE * fopen(char *nombrearchivo, char *modo);
Modos de apertura de ficheros
Modo Texto Binario Observaciones
Abrir para leer"r" "rb" Si no existe, se produce error
Crear para escribir"w" "wb" Si existe, se pierde el contenido
Abrir o crear para añadir"a" "ab" Si no existe, se crea
Abrir para leer y/o escribir"r+" "rb+" Debe existir
Crear para leer y/o escribir"w+" "wb+" Si existe, se pierde el contenido
Abrir o crear para añadir y/o leer"a+" "ab+" Si no existe, se crea

Mientras el fichero esté abierto, el descriptor correspondiente apunta a una estructura que contiene toda la información necesaria sobre el fichero:

Al finalizar un programa que utiliza ficheros:

En previsión de finalizaciones anómalas, tras las operaciones de lectura y/o escritura, es preciso cerrar los ficheros, utilizando la función fclose():

   int fclose(FILE *descriptor);
   FILE *pf;   /* descriptor a fichero */
   if ((pf=fopen("misdatos/prueba.x","w+")) == NULL) {
      puts("nNo es posible crear el fichero");
      exit(0);
   } else printf("nEl fichero se ha abierto");
                  /* Tras realizar todas las operaciones necesarias,
                es preciso cerrar el fichero antes de finalizar
                     el programa */
   fclose(pf);    /* El fichero ha quedado cerrado */

El carácter de fin de fichero está representado por la constante simbólica EOF, definida en stdio.h

   while (!feof(puntfile))
   {
      /* Operaciones sobre el fichero abierto */
   }
Entrada y salida de texto

Las funciones de lectura y escritura de caracteres en ficheros están definidas en stdio.h

   int fgetc( FILE *pf);
   int fputc( int car, FILE *pf);
   FILE *pf1, *pf2;
   char letra;
   pf1 = fopen("leer.txt", "r");
   letra = fgetc(pf1);     /* Lee un carácter */
   pf2 = fopen ("escribir.txt", "w");
   fputc(letra, pf2);      /* Escribe un carácter */
   fclose(pf1);
   fclose(pf2);

Las funciones de lectura y escritura de cadenas de texto en ficheros están definidas en stdio.h

   char * fgets(char *cad, int numcar, FILE *pf);
   int fputs(char *puntcad, FILE *pf);
   FILE *pf1, *pf2;
   char lect[50];
   char escr[]="Mensaje a guardar en el fichero";
   int num=50-1;
   pf1 = fopen("leer.txt", "r");
   fgets(lect, num, pf1);
      /* Lee una cadena de 49 caracteres de leer.txt */
   pf2 = fopen ("escribir.txt", "w");
   fputs(escr, pf2);
      /* Escribe la cadena "Mensaje a guardar en el fichero escribir.txt */
   fclose(pf1);
   fclose(pf2);
Lectura y escritura de datos binarios

Para la lectura de un conjunto de datos:

   unsigned fread(void *buf, unsigned numbytes, unsigned numdat, FILE *pf);

Para la escritura de un conjunto de datos:

   unsigned fwrite(void *buf, unsigned numbytes, unsigned numdat, FILE *pf);
   FILE *pf;
   float valor1=3.5, valor2;
   pf=fopen ("archivo.dat", "ab+");       /* "a+" en Unix */
   fwrite(&valor1, sizeof(valor), 1, pf); /* Escribe */
   fread(&valor2, sizeof(float), 1, pf);  /* Lee */
Entrada y salida por ficheros con formato
   int fprintf(FILE *pf, const char* cad_control, lista_argumentos);
   int fscanf(FILE *pf, const char* cad_control, lista_argumentos);
   fprintf(stdout, "Número: %d", num);
   printf("Número: %d", num);
   FILE *pf;
   int i = 100;
   char c = 'C';
   float f = 1.234;
   pf = fopen("prueba.dat", "w+");
   fprintf(pf, "%d %c %f", i, c, f);   /* Escribe en el fichero */
   fscanf(pf, "%d %c %f", &i, &c, &f); /* Lee los mismos datos en el fichero */
   fclose(pf);
Entrada y salida mediante acceso directo

El acceso a los ficheros puede hacerse:

Los punteros de tipo FILE apuntan a una estructura creada por el sistema operativo que controla las operaciones sobre ese fichero.

La función fseek(), definida en stdio.h, permite el movimiento aleatorio por el fichero abierto estableciendo una nueva posición para el apuntador de lectura-escritura:

   int fseek(FILE *pf, long nbytes, int origen);
   #define N 5                   /* Será la fila 5 */
   int matriz[20][4], *punt;     /* 20 filas y 4 columnas*/
   FILE *pf;
   punt = matriz;
 
      /* Apertura del fichero sin errores */
   fwrite(punt, sizeof(int), 20*4, pf);
      /* Escribe la matriz en un fichero */
   fseek(pf, sizeof(int)*4*N, SEEK_SET);
      /* Apunta a los datos de la fila N, al ser
         4*sizeof(int) el tamaño de una fila */
   fread(&matriz[N][0], sizeof(int), 4, pf);
      /* Lee los datos de la fila N */
Otras operaciones sobre ficheros

long ftell(FILE *pf);

void rewind(FILE *pf);

int remove(char *nombre_archivo);

int fflush(FILE *pf);

FILE * tmpfile(void));