Necesito para escribir datos en un archivo binario con C de e/s funciones. El siguiente código hace una excepción en tiempo de ejecución :


#include "stdio.h"

int main(int argc,char* argv[]) {
    FILE *fp = fopen("path_to_file.bin","wb");
    if(fp == NULL) {
        printf("error creating file");
        return -1;
    }
    int val = 4;
    fwrite((const void*)val,sizeof(int),1,fp);
    fclose(fp);
    return 0;
}

El código muere en el fwrite. Puede detectar lo que estoy haciendo mal? Al parecer, estoy tratando de acceder a los datos a 0x0000004 o algo por el estilo.

Gracias !

OriginalEl autor Geo | 2009-04-21

6 Comentarios

  1. 15
     fwrite((const void*)val,sizeof(int),1,fp);

    debe ser:

     fwrite((const void*) & val,sizeof(int),1,fp);

    Por CIERTO, si usted no utiliza el elenco, usted recibirá un mensaje de error detallado. Yesos tienden a ser utilizada por C (y C++) programadores mucho más a menudo de lo que debería ser – una buena regla de oro es «si se necesita un molde, por lo que probablemente equivocado».

    +1 por tu regla de oro.
    + 1 para que la regla. la tengo en una nota adhesiva en mi monitor.

    OriginalEl autor

  2. 24

    Creo que Neil respuesta puede ser mejorado. Me doy cuenta de que ya la han aceptado, así que esto es sólo para mostrar un poco de contraste (que es por qué no me acaba de editar su nuevo).

    fwrite(&val, sizeof val, 1, fp);

    Dos mejoras:

    • Ningún puntero de la fundición, ya que no es necesario en C y puede ocultar los errores.
    • Uso sizeof directamente en el objeto, ya que es lo que estás pasando un puntero. Hace un montón de sentido para mí, y es más seguro que repetir lo mismo una y con el nombre del tipo.
    +1 Buen puñado de puntos, ambos. Moraleja de la historia: prefieren como poco moldes de yeso y el uso de sizeof juiciosamente.
    ¿Puede por favor explicar por qué el elenco no es necesario? Yo no soy un programador de C … y me gustaría entender tanto como sea posible de su «magia».
    fwrite() espera un void* como primer argumento. Cualquier tipo de puntero puede ser utilizado en un void* se espera, sin la necesidad de fundición. void* efectivamente dice «necesito un puntero, no me importa qué tipo de puntos».
    No se requiere en C. en particular, con los punteros. Usted puede asignar un puntero a void a un puntero a cualquier tipo de objeto y viceversa

    OriginalEl autor unwind

  3. 5

    Añadir a Neil respuesta: esto funciona cuando la lectura y la escritura el archivo en la misma plataforma. Cosas pueden llegar a ser raro si eres de lectura/escritura a través de las plataformas con diferentes endianness.

    No sólo el peso, el tamaño puede variar.
    C es taaan no multi plataforma, en el archivo de escritura/lectura que usted necesita para hacer una aplicación para cada plataforma, la mayoría de las veces, diferentes de final de línea y marcadores de cosas como que se convierten en una pesadilla cuando se trata con el archivo de escritura/lectura a través de plataformas (kindda fuera de tema, de todos modos :P)

    OriginalEl autor dirkgently

  4. 0
    #include "stdio.h"
    
    int main(int argc,char* argv[]) {
        FILE *fp = fopen("path_to_file.bin","wb");
        if(fp == NULL) {
            printf("error creating file");
            return -1;
        }
        int val = 4;
        fwrite((const void*)val,sizeof(int),1,fp);

    Usted debe proporcionar una dirección no entero en sí mismo.

    Además, usted no debe usar el entero de tal manera:

    1. Que puede diferir en «endian» en equipos diferentes (como se mencionó)
    2. Que pueden diferir en tamaño. En los viejos ordenadores que puede ser de 1 o 2 bytes. En la mayoría de los modernos va a ser 4, pero puede ser de 8 (algunos equipos de 64 bits). En algunas extrañas arquitecturas que puede ser incluso de 36 bits. int32_t val = 4; fwrite((const void *)val, 4, 1, fp) debe resolver el problema.

    Usted puede pensar que el software no necesita ser portado. Bien, muchos diseñadores (software y hardware) realizados en los mismos supuestos. A veces es demasiado costoso como para no hacer de ellos -, pero en este caso es sólo una cuestión de unos controles adicionales.

        fclose(fp);
        return 0;
    }

    OriginalEl autor Maciej Piechotka

  5. 0

    También me enfrentaba a este tipo de problema. Así que esta es mi solución.

    fwrite(val, sizeof(val[0], sizeof(val)/sizeof(val[0]), fp);

    OriginalEl autor Lasith Niroshan

  6. 0

    Al parecer, estoy tratando de acceder a los datos a 0x0000004 o algo por el estilo.

    int val = 4

    Que ahí está el problema. fwrite está diseñado para trabajar con cadenas, y como tal, su primera entrada es un puntero, la ubicación de una cadena en la memoria. Se pasa el valor de val directamente (4) en lugar de la dirección de val a fwrite; sin embargo, la memoria en 0x00000004 no es válida la memoria de programa y por lo tanto un error.

    Para solucionar este problema, cambie esto:

    fwrite((const void*)val,sizeof(int),1,fp);

    A esto:

    fwrite((const void*)&val, sizeof(int), 1, fp);

    El «&» operador indica la ubicación de val. Esta podría ser una dirección válida en la memoria.

    OriginalEl autor Adrian Zhang

Dejar respuesta

Please enter your comment!
Please enter your name here