La administración de errores es y siempre será una buena práctica de programación, ya que es posible que tengamos que idear con problemas o condiciones de errores no esperadas. Veamos que nos ofrece el lenguaje C para administrar los errores.
Veamos algunas funciones de la biblioteca estándar (ANSI/ISO C) que da soporte para tratar los errores. Estas funciones detectan el problema, nos permite informar al usuario de lo que ha sucedido y nos permiten controlar como y cuando termina un programa.
1 abort
Esta función devuelve un valor que indica al sistema operativo que el programa termino sin éxito (por lo que ha abortado por alguna razón desconocida). Simplemente produce que el programa cierre de forma anormal. Esto hace que las funciones de restauración no se ejecuten.
Al ejecutar el siguiente ejemplo notaremos que no se ejecutan las siguientes funciones después de abort().
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
puts("Mi secreto es....\n");
abort();
puts("... pero no le digas a nadie ...");
exit(EXIT_SUCCESS);
}$ cc -o abort abort.c $ ./abort Mi secreto es.... Cancelado
2 exit y atexit
La función exit() al igual que abort(), devuelve un valor al sistema operativo y termina la ejecución, sin embargo si permite ejecutar las funciones de limpieza como atexit(). Y se ejecutara despues de realizar la limpieza.
La función exit() no regresa ningún valor a si misma, pero contiene un argumento de entrada “int status” que es el valor que regresará al sistema operativo ya sea EXIT_SUCCESS o EXIT_FAILURE. Esto se puede ver en su prototipo:
#include <stdlib.h> void exit(int status);
La función atexit() registra un función determinada y la ejecutará al finalizar el programa que termine de forma correcta, ya sea con exit(EXIT_SUCCESS); o return 0.
La función que se registre con atexit() no debe aceptar argumentos y no debe regresar ningún valor. Tal como se indica es su prototipo:
#include <stdlib.h> int atexit(void (*funtion)(void));
Veamos un ejemplo de como utilizar estas funciones correctamente.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void imprimeSaludo(void)
{
printf("Hola mundo...\n");
}
if (atexit(imprimeSaludo) != 0)
{
fprintf(stderr, "El registro de la función imprimeSaludo ha fallado.");
exit(EXIT_FAILURE);
}
printf("Ultimo mensaje a imprimir, eso creo...\n");
exit(EXIT_SUCCESS);
}$ cc -o exit exit.c $ ./exit Ultimo mensaje a imprimir, eso creo... Hola mundo...
3 errno
Las funciones de la biblioteca establecen la variable global errno con un valor distinto a 0 cuando existe un error. En caso de utilizar la variable más de una vez, se recomienda establecerla igualándola a 0. La variable se encuentra en el archivo errno.h.
#include <errno.h> // Restablecer la variable errno = 0;
Veamos un ejemplo de como utilizarla.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
int main(void)
{
double resultado;
resultado = sqrt((double) -5);
if (errno)
{
perror("Error debido a");
errno = 0;
} else {
printf("Resultado = %f\n", resultado);
}
exit(EXIT_SUCCESS);
}$ cc errno.c -o errno -lm $ ./errno Error debido a: Numerical argument out of domain
4 perror
Esta función imprime una cadena que nosotros asignamos y establece la variable errno con un valor que describe el último error, la descripción la da el sistema operativo. El prototipo de la función es el siguiente.
#include <stdio.h> #include <errno.h> void perror(const char *s);
Veamos un ejemplo más.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
int main(void)
{
double resultado;
errno = 0;
resultado = sqrt((double) -5);
if (errno)
perror("Fallo en sqrt(-5)");
exit(EXIT_SUCCESS);
}$ cc -o perror perror.c -lm $ ./perror Fallo en sqrt(-5): Numerical argument out of domain
5 strerror
Al igual que perror(), la función strerror() muestra un mensaje cuando ocurre un error.
#include <string.h> char *strerror(int errnum);
Veamos el último ejemplo:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <math.h>
int main(void)
{
double resultado;
errno = 0;
resultado = sqrt((double) -5);
if (errno)
printf("Error en sqrt(-5) %s\n", strerror(errno));
exit(EXIT_SUCCESS);
}$cc -o strerror strerror.c -lm $ ./strerror Error en sqrt(-5) Numerical argument out of domain
Observando la salida de los ejemplos de perror() y strerror() notamos que:
perror("Mensaje");es lo mismo que:
printf("Mensaje: %s\n", strerror(errno));