文件返回垃圾,但正确写入

时间:2012-06-14 02:21:29

标签: c file fopen fwrite

我正在将结构写入文件,但它返回垃圾。这是我的代码:

ptFile = fopen("funcionarios.dat", "ab+");
fwrite(&novoFunc, sizeof(strFunc), 1, ptFile);

在fwrite之前和之后struct novoFunc的值不是垃圾。 但是,当我返回文件值时:

ptFile = fopen("funcionarios.dat", "rb+");
[...]

fseek(ptFile, i*sizeof(strFunc), SEEK_SET); //on the loop, i goes from 0 to total structs
fread(&funcionario, sizeof(strFunc), 1, ptFile);

printf("Code: %d; Name: %s; Address: %s; CPF: %d; Sales: %d\n", funcionario.codigo, funcionario.nome, funcionario.endereco, funcionario.cpf, funcionario.numVendas);

知道为什么吗?代码工作正常,我不记得做了有意义的改变。

提前致谢

编辑:结构定义

typedef struct func{

    int codigo;
    char nome[50];
    char endereco[100];
    int cpf;
    int numVendas;
    int ativo;


} strFunc;

Edit2:它更奇怪:它在linux上工作正常(使用netbeans和gcc编译器),但它不适用于Windows(devcpp和codeblocks)。好吧,整个代码都在这里:

http://pastebin.com/XjDzAQCx

函数cadastraFucionario()注册用户,当我使用listaFuncionarios()时,列出所有已注册的数据,它返回垃圾。这是listaFuncionarios()返回的打印:

http://img715.imageshack.us/img715/3002/asodfadhf.jpg

对不起,代码不是英文

3 个答案:

答案 0 :(得分:2)

你说:“代码工作正常,我不记得做出有意义的改变。”

当它工作正常时,它会在你的文件中写下一些结构。

也许以后它仍然可以正常工作,并在文件末尾添加了一些额外的结构。原始数据仍保留在文件的开头。因此,当您阅读文件的开头时,您将读取原始数据。也许

你确定你读过垃圾吗?你确定你不只是阅读旧数据吗?

在您的代码中:

ptFile = fopen("funcionarios.dat", "ab+");

为某些目的而做的追求是正确的,但对其他目的则不然。你需要wb +吗?

答案 1 :(得分:1)

以下是函数retornaIndice中的两个问题。

while(!feof(ptFile)){
    fseek(ptFile, sizeof(strFunc)*i, SEEK_SET);
    fread(&tmpFunc, sizeof(strFunc), 1, ptFile);

你没有检查fread的结果。阅读完最后一条记录后,还没有达到eof,所以你会尝试另一次阅读。该读取将达到eof并将返回0,但是您没有检查该0,因此您将使用垃圾数据并在下次while语句测试时退出循环。

if(codigo != 0 && tmpFunc.ativo){                   
    if(tmpFunc.codigo == codigo){
        return i;                               
    }

如果此时检测到问题,则不要关闭ptFile。泄漏的句柄不应该导致垃圾数据写入文件,但它也不会激发信心。

您的其他一些功能也有同样的错误。

答案 2 :(得分:1)

此:

  

它在linux上工作正常......但它不在Windows上

是一个大红旗。 Windows具有与“二进制”文件不同的“文本”文件。在Linux和其他Unix上,没有区别。

你的资源中有两行突出:

fopen("funcionarios.dat", "rb+");

以后

fopen("funcionarios.dat", "r+");

也就是说,有时您以“二进制”模式打开文件,有时以“文本”模式打开文件。如果您打算读取或写入非文本数据,请确保始终以“二进制”模式打开任何文件(即,使用模式字符串中的b)。