El manejo de errores en el archivo de la apertura de

[Pregunta 1]

Cuando abro un archivo en una función, en general, he de hacer algo como esto:

int read_file (char *filename)
{
    FILE *fin;

    if ( !(fin = fopen(filename, "r")) )
        return 1;

    /* ... */

    return fclose(fin);
}

int main ()
{
    char filename[100];

    if ( read_file(filename) )
    {
        perror(filename);
        exit(1);
    }

    return 0;
}

Generalmente 0 valor de retorno es de los errores (¿verdad?) entonces puedo cambiar el código anterior en:

int read_file (char *filename)
{
    FILE *fin;

    if ( !(fin = fopen(filename, "r")) )
        return 0;

    /* ... */

    return !fclose(fin);
}

int main ()
{
    char filename[100];

    if ( !read_file(filename) )
    {
        perror(filename);
        exit(1);
    }

    return 0;
}

Pero creo que el primer código es más limpio.

Otra opción es sólo cambiar return 1; en return -1; (en el primer código que escribí).

¿Cuál es la mejor versión?

[Pregunta 2]

Si tengo que manejar más errores, ¿es correcto que un código como este?

int read_file (char *filename, int **vet)
{
    FILE *fin;

    if ( !(fin = fopen(filename, "r")) )
    {
        perror(filename);
        return 1;
    }

    * vet = malloc (10 * sizeof(int));
    if ( *vet == NULL )
    {
        perror("Memory allocation error.\n");
        return 1;   
    }

    /* ... */

    return fclose(fin);
}

int main ()
{
    char filename[100];
    int *vet;

    if ( read_file(filename, &vet) )
        exit(1);

    return 0;
}
  • no (fin = fopen(filename, "r") ser siempre así?
  • En general usamos 0 como el valor predeterminado de error devueltos como 0 se refiere a false y no valores nulos se refiere a true. Pero cuando los diferentes errores debe ser manejado podemos usar valores negativos para los errores. En su segunda pregunta, es mejor devolver valores diferentes para los distintos errores para ser capaz de saber exactamente el error que causó el error.
  • Es más habitual en C para utilizar un valor negativo como indicador de error y cero o un número positivo para el éxito. En su función, cero o positivo valor de retorno podría indicar el número de vecs que eran de lectura, donde cero significa que el archivo está bien, pero no tenía ninguna vets en ella. Me gusta la idea de utilizar diferentes valores negativos (tal vez enums) para indicar los diferentes errores.
  • Su comentario de que 1 es «en general, de los errores», probablemente refiriéndose al programa de códigos de salida. Generalmente exit(0) se refiere a la ejecución correcta y cualquier otro valor indica que el programa terminó con algún tipo de error. Funciones dentro del programa son libres de usar cualquier esquema es conveniente errores de la señal. Por ejemplo, algunas personas les gusta usar setjmp longjmp para este propósito
  • If the file is successfully opened, the function returns a pointer to a FILE object that can be used to identify the stream on future operations. Otherwise, a null pointer is returned.[cplusplus.com]
  • sí, Pero usted está asignando, que regresó FILE pointer a fin, y el resultado de esta asignación es siempre cierto. como en el caso de int a; (a=5) siempre es cierto. Si el archivo se abre correctamente, la declaración será if(fin=<some value>) otro sabio que será if(fin=NULL), no tanto para ser verdad?
  • No, como usted dice «otro sabio que será if(fin=NULL)«, entonces en este caso es falsa (enlace).
  • sí.. yo estaba discutiendo acerca de una cosa totalmente diferente (yo era estúpido pensar así). Este es correcta. aunque no tengo ni la confusión acerca de NULL.

InformationsquelleAutor | 2014-01-21

1 Kommentar

  1. 3

    Re P1:

    a) la Mayoría de las funciones POSIX, devuelven -1 (o <0) por errores, no 0. Ver (por ejemplo) open(), close(), read(), write() y así sucesivamente. La excepción es el POSIX llamadas que devuelven punteros, por ejemplo,fopen(), que devuelve un FILE *. Estos retorno NULL en caso de error.

    b) código de mi código para que funcione como las funciones POSIX, que es similar a la de las vísceras de muchos programas de linux. Yo diría que se trata de ‘el UNIX estándar de C’. Sin embargo, muchos programas de C++ y Java uso de programas de true para el éxito y false para el fracaso. Cuando estos programadores mover a C, se uso 1 para el éxito, y 0 para el fracaso. Esto no es malo, pero no causar confusión (bueno, me causa confusión). El peor resultado es cuando ambas normas se utilizan en el mismo programa. Escoger un estándar, y apegarse a él es más importante que el estándar elegido.

    c) Mi propia elección (en relación a Q1), sería para volver -1 en caso de error (es decir, según su «otra elección» de la línea).

    Re P2: en su mayoría a la derecha, sí.

    a) Si el programa es exitoso, mejor exit(0) de return 0 creo.

    b) Bastante donde perror es hasta usted. Tal vez usted quiere imprimir el error en main().

    c) el Uso de perror seguido inmediatamente por exit(1) (o tal vez un código de salida distinto dependiendo del error) es razonable normal si usted no tiene ninguna limpiar a hacer o limpiar dentro de atexit.

    d) Si se devuelve el resultado de fclose() en caso de error, luego la de regreso si fopen falla debe ser -1 (o EOF) no 1 como si fclose() falla devuelve EOF (también conocido como -1).

    e) Nit: su main función debe tener parámetros (por ejemplo,int main(char **argv, int argc))

    • (Q2b) «Bastante donde perror es hasta usted. Tal vez usted quiere imprimir el error en main() Pero si yo uso perror en main() yo no puedo diferenciar los errores! (Q2d) «Si va a devolver el resultado de fclose() en caso de error, luego la de regreso si fopen falla debe ser -1 (o EOF) no 1 como si fclose() falla devuelve EOF (también conocido como -1).» Pero si fopen falla vuelve a main(): que no llegan hasta la fclose().
    • (Q2e) «Nit: su principal función debe tener parámetros (por ejemplo, int main(char **argv, int argc))« Si usted no utiliza el main() parámetros que no se puede escribir en ellos. De documentos Estándar 3.6.1.2 Función Principal: «deberá tener un tipo de retorno de tipo int, pero de lo contrario, su tipo de aplicación definido. Todas las implementaciones permitirá a ambas de las siguientes definiciones de los principales: int main() { / ... / } y int main(int argc, char* argv[]) { / ... / }«

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea