使用fread读取文件之后,显示结果不正确

时间:2021-07-30 16:49:25

/**
  *把结构数组中的内容保存到指定的文件中
  */

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

#define MAXTITL 40
#define MAXAUTH 40
#define MAXBOKS 100

struct book {
    char title[MAXTITL];
    char author[MAXAUTH];
    float value;
};

int main(void)
{
    FILE *fp;
    int count=0, filecount;
    int index;
    int size = sizeof(struct book);

    struct book library[MAXBOKS];

    if((fp=fopen("book.dat", "a+b")) == NULL){
        printf("Error in openning book.dat.\n");
        exit(1);
    }
    rewind(fp);

    /*使用fread读取book.dat中的信息,使用printf显示所读取的信息。*/
    /*printf显示信息不正确,缺少书名和作者信息*/
    while(fread(&library[count], size, 1, fp) == 1 && count<MAXBOKS){
        if(count == 0)
            printf("Current book list of the book.dat: \n");
        printf("%s by %s: $%.2f.\n", library[count].title,
                    library[count].author, library[count++].value);
        //问题在此,printf不能正确显示书名和作者信息
    }

    filecount = count;
    if(count == MAXBOKS){
        printf("Upper to the limmit of the book.dat.\n");
        exit(2);
    }

    printf("Now, add the new list.\nPlease enter the title: ");
    while(fgets(library[count].title, MAXTITL-1, stdin) != NULL &&
                library[count].title[0] != '\n' && count<MAXBOKS){
        library[count].title[strlen(library[count].title)-1] = '\0';
        printf("Please enter the author: ");
        fgets(library[count].author, MAXAUTH-1, stdin);
        library[count].author[strlen(library[count].author)-1] = '\0';
        printf("Please enter the value: ");
        scanf("%f", &library[count++].value);
        if(getchar() == '\n')
            ;
        if(count < MAXBOKS)
            printf("Please enter the next title: ");
    }

    if(count > 0){
        printf("Now, there is your library:\n");
        for(index=0; index<count; index++)
            printf("%s by %s: $%.2f.\n", library[index].title,
                        library[index].author, library[index].value);
        fwrite(&library[filecount], size, count-filecount, fp);
    }
    else
        printf("No list? So bad...\n");

    printf("Bye Bye!\n");

    return 0;
}

程序文件执行结果:
引用
Now, add the new list.
Please enter the title: The C programming
Please enter the author: K&R
Please enter the value: 68.3
Please enter the next title: ABC of Python
Please enter the author: R&N
Please enter the value: 70.2
Please enter the next title: Javascript
Please enter the author: 56
Please enter the value: 74
Please enter the next title: 
Now, there is your library:
The C programming by K&R: $68.30.
ABC of Python by R&N: $70.20.
Javascript by 56: $74.00.
Bye Bye!
//再次执行该程序,结果如下
Current book list of the book.dat: 
 by : $68.30.
 by : $70.20.
 by : $74.00.

Now, add the new list.
Please enter the title: ^C

使用示例程序文件读取book.dat中的内容,表明存储在book.dat的内容是正常的。
请教各位,问题出在哪里?谢谢。

6 个解决方案

#1


txt 文件的读写,用 fscanf,fprintf
binary文件 用 fread,fwrite

#2


楼上说得不对,楼主的读写是的的,错的地方是
printf("%s by %s: $%.2f.\n", library[count].title,                    library[count].author, library[count++].value);
不应该在打印里面使用++,用于函数调用的压栈顺序,会导致前面的count被+1了,所以无法打印出来,你吧count++改成count,然后++单独写一行。

#3


引用 2 楼 Idle_Cloud 的回复:
楼上说得不对,楼主的读写是的的,错的地方是
printf("%s by %s: $%.2f.\n", library[count].title,                    library[count].author, library[count++].value);
不应该在打印里面使用++,用于函数调用的压栈顺序,会导致前面的count被+1了,所以无法打印出来,你吧count++改成count,然后++单独写一行。

++
确实是这个问题,函数调用,最好不要使用有副作用的代码,因为未定义。

#4


推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

不要把
fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待

fopen("...","...b");fread,fwrite,fclose  //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待
弄混了

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址;
人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

#5


引用 2 楼 Idle_Cloud 的回复:
楼上说得不对,楼主的读写是的的,错的地方是
printf("%s by %s: $%.2f.\n", library[count].title,                    library[count].author, library[count++].value);
不应该在打印里面使用++,用于函数调用的压栈顺序,会导致前面的count被+1了,所以无法打印出来,你吧count++改成count,然后++单独写一行。

谢谢指点,问题解决了。

#6


引用 4 楼 zhao4zhong1 的回复:
推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

不要把
fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待

fopen("...","...b");fread,fwrite,fclose  //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待
弄混了

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址;
人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

谢谢。

#1


txt 文件的读写,用 fscanf,fprintf
binary文件 用 fread,fwrite

#2


楼上说得不对,楼主的读写是的的,错的地方是
printf("%s by %s: $%.2f.\n", library[count].title,                    library[count].author, library[count++].value);
不应该在打印里面使用++,用于函数调用的压栈顺序,会导致前面的count被+1了,所以无法打印出来,你吧count++改成count,然后++单独写一行。

#3


引用 2 楼 Idle_Cloud 的回复:
楼上说得不对,楼主的读写是的的,错的地方是
printf("%s by %s: $%.2f.\n", library[count].title,                    library[count].author, library[count++].value);
不应该在打印里面使用++,用于函数调用的压栈顺序,会导致前面的count被+1了,所以无法打印出来,你吧count++改成count,然后++单独写一行。

++
确实是这个问题,函数调用,最好不要使用有副作用的代码,因为未定义。

#4


推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

不要把
fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待

fopen("...","...b");fread,fwrite,fclose  //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待
弄混了

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址;
人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

#5


引用 2 楼 Idle_Cloud 的回复:
楼上说得不对,楼主的读写是的的,错的地方是
printf("%s by %s: $%.2f.\n", library[count].title,                    library[count].author, library[count++].value);
不应该在打印里面使用++,用于函数调用的压栈顺序,会导致前面的count被+1了,所以无法打印出来,你吧count++改成count,然后++单独写一行。

谢谢指点,问题解决了。

#6


引用 4 楼 zhao4zhong1 的回复:
推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

不要把
fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待

fopen("...","...b");fread,fwrite,fclose  //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待
弄混了

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址;
人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

谢谢。