fwrite和fread结构

时间:2014-12-27 20:21:00

标签: c struct fwrite fread

我想将这个结构写入二进制文件,然后从二进制文件中读取它,但它不起作用。结构tLista的数组为impresoraimpresora的结构为tColal->oc的值为256883222,显然不正确。该值取决于loadData函数。

typedef char tcadena[13];

typedef struct 
{   
    tcadena nombres [TAM];
    int lectura;
    int escritura;
}tCola; 

typedef struct 
{
    char nombre [21];
    int pendientes;
    tCola cola;
}impresora;

typedef struct 
{
    impresora lista[TAMI];
    int oc;
}tLista;

...

void finalizar(tLista *l)
    {
    /* Apertura del fichero de destino, para escritura en binario*/
    FILE *fichero;
    fichero = fopen ("listaImpresoras.bin", "wb");
    if (fichero==NULL)
    {
        printf("No se puede abrir listaImpresoras.bin");
    }
    else
    {
        fwrite(l, sizeof(*l), 1, fichero);
    }
    fclose(fichero);
}

...

void inicializarLista (tLista *l)
{ 
    FILE *fichero;
    fichero=fopen("listaImpresoras.bin", "r");
    if(fichero==NULL)
    {
        printf("No existe el fichero listaImpresoras.bin\n");
        l->oc=0;
    }
    else
    {
        fread(l, sizeof(*l), 1, fichero);
    }
    fclose(fichero);
}

...

int main(int argc, char* argv[])
{
    tLista l;
    inicializarLista(&l);
    loadData(&l); //printf and scanf (user) charge the list
    finalizar(&l);
    return 0;
}

2 个答案:

答案 0 :(得分:2)

你有几个问题,但主要问题是,你没有正确地初始化tList l;结构,下面我发布了一些可能帮助你看到问题的代码,它可行我测试了它

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define TAM 100
#define TAMI 100

typedef char tcadena[13];

typedef struct
{
    tcadena nombres[TAM];
    int lectura;
    int escritura;
}tCola;

typedef struct
{
    char nombre[21];
    int pendientes;
    tCola cola;
}impresora;

typedef struct
{
    impresora lista[TAMI];
    int oc;
}tLista;

void finalizar(tLista *l)
{
    /* Apertura del fichero de destino, para escritura en binario*/
    FILE *fichero;

    fichero = fopen ("listaImpresoras.bin", "w");
    if (fichero == NULL)
    {
        printf("No se puede abrir listaImpresoras.bin");
    }
    else
    {
        fwrite(l, sizeof(*l), 1, fichero);
        /* solo debes llamar fclose(fichero); si (fichero != NULL) */
        fclose(fichero);
    }
    /* fclose(fichero); esto va a ser ejecutado, aunque (fichero == NULL) */
}

void inicializarLista(tLista *l)
{
    FILE *fichero;

    fichero = fopen("listaImpresoras.bin", "r");
    if (fichero == NULL)
    {
        printf("No existe el fichero listaImpresoras.bin\n");
        l->oc = 0;
    }
    else
    {
        fread(l, sizeof(*l), 1, fichero);
        /* solo debes llamar fclose(fichero); si (fichero != NULL) */
        fclose(fichero);
    }
    /* fclose(fichero); esto va a ser ejecutado, aunque (fichero == NULL) */
}

void loadData(tLista *l)
{
    int i;
    for (i = 0 ; i < 10 ; i++)
    {
        l->oc++;
    }
}

int main(int argc, char* argv[])
{
    tLista l;

    /* tienes que iniacializar todos los campos de `l`. */
    memset(&l, 0, sizeof(l));
    /* si no quieres hacerlo asi, entonces puede que
     *
     * l.oc = 0;
     *
     * sea suficiente, pero quedan los otros campos.
     *
     * al no inicializar explicitamente los campos, contienen
     * basura aleatoria, que has estado escribiendo en el archivo.
     */                               

    inicializarLista(&l);
    printf("%d\n", l.oc);

    loadData(&l); //printf and scanf (user) charge the list

    finalizar(&l);
    return 0;
}

当您未明确初始化tLista l;中的所有字段时,它们包含您已写入文件的垃圾。

另外,如果您检查fopen()是否成功,为什么要尝试fclose()生成的NULL?如果fopen()返回NULL,您必须退出该函数而不fclose fopen NULL的结果,因为它{{1}}。

答案 1 :(得分:1)

以下代码:

  • 干净利落地编译,
  • 正确初始化tLista结构,
  • 从结构定义
  • 中删除模糊处理
  • 发生错误时退出程序,
  • 在退出前将错误原因正确写入stderr

修订代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAM  (2)
#define TAMI (2)

struct tCola
{
    char nombres [TAM][13];
    int lectura;
    int escritura;
};

struct impresora
{
    char nombre [21];
    int pendientes;
    struct tCola cola;
};

struct  tLista
{
    struct impresora lista[TAMI];
    int oc;
};

void loadData( struct tLista *);

void finalizar(struct tLista *l)
{
    /* Apertura del fichero de destino, para escritura en binario*/
    FILE *fichero;

    if( NULL == (fichero = fopen ("listaImpresoras.bin", "wb") ) )
    { // then, fopen failed
        perror("fopen failed");
        printf("No se puede abrir listaImpresoras.bin\n");
        exit(EXIT_FAILURE);
    }

    // implied else, fopen successful

    fwrite(l, sizeof(struct tLista), 1, fichero);
    fclose(fichero);
}  // end function: finalizar



void inicializarLista (struct tLista *l)
{
    FILE *fichero;

    if( NULL == (fichero=fopen("listaImpresoras.bin", "r") ) )
    { // then, fopen failed
        perror(" fopen failed");
        printf("No existe el fichero listaImpresoras.bin\n");
        exit(EXIT_FAILURE);
    }

    // implied else, fopen successful

    fread(l, sizeof(*l), 1, fichero);
    fclose(fichero);
} // end function: inicializarLista



int main()
{
    struct tLista l;

    memset( &l, 0x00, sizeof(struct tLista) );
    inicializarLista(&l);
    loadData(&l); //printf and scanf (user) charge the list
    finalizar(&l);
    return 0;
} // end function: main