2009-07-29 9 views
6

Me gustaría guardar una estructura en un archivo. Me gustaría realizar una función que hace que esto funcione. Intenté este código pero no funcionó.cómo puedo guardar la estructura en el archivo .... C lang

struct utilisateur // enregestrement pour sauvegarder les details de l utilisateur 
{ 
char nom[20]; 
char prenom[20]; 
int place; 
char depart[20]; 
char arrive[20]; 
char sexe; 
int nwagon; 
}; 

struct utilisateur utilis; 
struct utilisateur *Table[48]; 

void crea_fich(struct utilisateur *Tutilis) 
// creation un fichier, vous introduiez le nom, et le sotcker par enreg 
{ 
    FILE *f; 
    if (f!==0) 
    { 
     printf("error in the name of file \n"); 
     exit(1); 
    } 
    if (f=fopen(futilis,"w")==Null){ 
     fprint("We can't creat file \n"); 
     exit(1); 
    } 
    else{ 
     f=fopen("futilis.dat","wb"); 
     fwrite(Tutilis ,sizeof(utilisateur),1,f); 
    } 
} 
+0

Tiene mucho ruido en ese fragmento de código, por no mencionar los problemas de formato (y la declaración de Tabla parece extraña). ¿Cómo es el resultado de fwrite diferente de lo que esperabas, suponiendo que tu código real llega tan lejos? – brendan

+0

Hola. ¿Puedes poner un pequeño formato de texto en tu pregunta? Hará que sea mucho más fácil de leer. – anderstornvig

+0

¿Qué intentas hacer con "if (f! == 0)"? En primer lugar, "f" no está inicializado, por lo que usarlo en ese punto es simplemente incorrecto. En segundo lugar, no hay operador "! =="; Quiere decir "! =". –

Respuesta

0

me vería en los nombres de los símbolos en primer lugar, al igual que NULL y fprint, por no mencionar que raro \0. Como una idea adicional, debe cerrar el archivo después de escribir para asegurarse de que se vacíe en el disco, y verificar que la variable futilis es un char* que contiene una ruta válida y escribible.

6

No. Necesita escribir sus miembros de datos individualmente, uno a la vez. No debe copiar ciegamente la representación de memoria de su estructura en el búfer de salida de archivo (que está claro que está tratando de hacer). Escribir los archivos de esa manera hará que los archivos no sean portátiles (no serán legibles, excepto en la plataforma en que fueron escritos), debido a la endianancia y al relleno específico de la plataforma de los elementos de la estructura.

+3

bueno, nunca dijo que se requiera la portabilidad, por lo que no hay nada explícitamente incorrecto con la noción de escribir estructuras directamente en el sistema de archivos. Conozco uno o dos front-ends de idiomas, por ejemplo, que hicieron exactamente eso con sus datos de árbol analizado. –

5

Sólo un ejemplo sencillo :)

// your struct 
struct Data 
{ 
    int first; 
    double second; 
    char third[10]; 
}; 

luego escribir la estructura!

struct Data data = {22, 4.0, "Hi"}; 
FILE* output; 

output = fopen("Data.dat", "wb"); 

fwrite(&data, sizeof(data), 1, output); 

fclose(output); 

¡Finalmente lea los datos del archivo que ha creado!

struct Data data; 
FILE* input; 

input = fopen("Data.dat", "rb"); 

fread(&data, sizeof(data), 1, input); 

// you got the data from the file! 

fclose(input); 

Los archivos binarios son pesadillas si no escritos y leídos prudentemente. Debe ocuparse de muchas cosas sobre la arquitectura donde se creó el archivo y dónde se leerá. Endianess y el tamaño de las variables son los más importantes. Además, si tiene punteros dentro de su struct, el puntero que se escribirá en el archivo no los datos reales a los que apunta el puntero. Lo sentimos, no editar el código, ya que está lleno de errores de compilación :)

He eliminado mi primera respuesta porque era tan malo, lo siento :)

+0

Esto es solo un pequeño detalle, pero abriste el archivo en modo "r" y escribiste datos binarios ("r" es texto, "rb" es binario). Si bien esto no hará una diferencia en Linux, podría ser cuando este código se ejecute en Windows, FYI. – mox1

+0

Lo siento, no soy un buen hombre C :) Uso C++ regularmente. – AraK

6

Prueba esto, y luego si eso no es hacer lo Si lo desea, intente explicar cómo difiere de lo que desea.

void crea_fich(struct utilisateur *Tutilis) 
{ 
    FILE *f; 
    size_t nwritten; 

    f = fopen("futilis.dat","wb"); 

    if (f == NULL) 
    { 
     fprintf(stderr, "Cannot open file for writing.\n"); 
     exit(1); 
    } 

    nwritten = fwrite(Tutilis, sizeof Tutilis[0], 1, f); 
    fclose(f); 

    if (nwritten < 1) 
    { 
     fprintf(stderr, "Writing to file failed.\n"); 
     exit(1); 
    } 
} 
+3

Esto (y la función inversa que utiliza 'fread()') funcionará en cualquier arquitectura de máquina; sin embargo, no es portátil para otras arquitecturas. Esto probablemente no importa en el contexto, pero vale la pena mencionarlo para completarlo. –

6

Michael S is right; usar fwrite con una estructura es muy poco portable. Pero supongamos que no te importa eso y quieres algo fácil de escribir que funcione.

El problema en su código es que se ha roto la regla de oro de sizeof: nunca use sizeof con un nombre de tipo. En su lugar, debe usar sizeof con un valor l, y casi siempre con la desreferencia de otro argumento. Por lo tanto,

Tutilis = malloc (sizeof (*Tutilis)); 
    ... 
fwrite(Tutilis, sizeof (*Tutilis), 1, f); 

Si sigue esta receta, es mucho más difícil obtener el tamaño incorrecto.

+1

Apenas lo llamaría una "regla de oro". Toneladas de código y hoy llamadas sizeof en non lvalues. El propio sitio web MSDN de Microsoft muestra cómo llamarlo con un nombre de tipo. http://msdn.microsoft.com/en-us/library/4s7x1k91.aspx – mox1

+0

@James: Es perfectamente legal, simplemente no es una práctica de programación muy robusta. No saltarías por un precipicio solo porque MSDN te mostró cómo, ¿o sí? :-) –

1

Me doy cuenta de que esta es una publicación anterior, pero aparece cuando la gente busca esta información, así que daré mi propia solución.

Esto es básicamente lo que he usado en uno de mis juegos. De hecho, tengo un código adicional de biblioteca adicional en mi propia función para diálogos, pero esto es esencialmente eso. Escribo datos individualmenteNo creo que tenga una estructura para estos datos, pero no hay diferencia, solo escriba los miembros de la estructura individual por separado. Como se mencionó, es mejor así.

// returns 1 if successful, 0 if not 
int savemap(const char *map_name) 
{ 
    FILE *file = NULL; 

    // open the file in write binary mode 
    file = fopen(map_name, "wb"); 

    // always check return values to see if it was opened okay 
    if(file == NULL) { 
     fprintf(stderr, "Error opening file for writing.\n"); 
     return 0; 
    } 

    // write file ID, version and pills 
    fwrite(MAP_ID, sizeof(char), strlen(MAP_ID)+1, file); 
    fwrite(&MAP_VER, sizeof(unsigned char), 1, file); 
    fwrite(&pills, sizeof(unsigned short), 1, file); 

    // write the map data (unsigned int map[315]) 
    fwrite(&map, sizeof(unsigned int), 315, file); 

    // never forget to close the file 
    fclose(file); 

    return 1; 
} 
+2

¿No son los códigos de retorno normalmente 0 == éxito,> 0 de lo contrario? –

Cuestiones relacionadas