c语言 用fwrite输出数据后,想要用fread读取就不能! 第二个代码哪里出错了?

第一个
#include<stdio.h>
#define SIZE 2

typedef struct //typedef
{
char name[10];
int num;
int age;
char addr[15];
}student;

student stu[SIZE];

void save()
{
FILE *fp;
int i;
if((fp = fopen("dat.txt","wb")) == NULL)
{
printf("无法打开此文件!\n");
return;
}
for(i = 0; i < SIZE; i++)
if(fwrite(&stu[i], sizeof(student), 1, fp) != 1)
{
printf("文件写入错误。!\n");
}
fclose(fp);
}

void main()
{
int i;
for(i = 0; i < SIZE; i++)
scanf("%s,%d,%d,%s",&stu[i].name,&stu[i].num,&stu[i].age,&stu[i].addr);
save();
}

第二个
#include<stdio.h>
#include<stdlib.h>
#define SIZE 2

typedef struct
{
char name[10];
int num;
int age;
char addr[15];
}student;

student stu[SIZE];
int i;

void load()
{
FILE *fp;

if(!(fp = fopen("dat.txt", "rb")))//打开文件
{
printf("Cannot open the file!");
return;
}

for(i = 0; i < SIZE; i++)
{
fread(&stu[i], sizeof(student),1 , fp);//读取数据块!
}
fclose(fp);
}

void main()
{

for(i = 0; i < SIZE; i++)
{
printf("%s%d%d%s", stu[i].name, stu[i].num, stu[i].age, stu[i].addr );
}
}

读文件程序
void main()
{
load(); 少了这句
for(i = 0; i < SIZE; i++)
{
printf("%s%d%d%s", stu[i].name, stu[i].num, stu[i].age, stu[i].addr );
}
}

如果作为了解C语言编程原理,你完全可以这样写。但是作为正规文件数据读写程序来说。
这些保存数据的方式是错误的。而且是非常危险的。

写文件程序和读文件程序在同一台电脑中不会看出问题。
一旦,一个程序在32位系统中,另一个程序在64位系统中,就可能出现问题。
或者一个计算机的处理器使用的大端字节优先序,另一个计算机的处理器使用小端字节优先序。或者,这两个程序使用不同版本的编译器编译。都会出错的。

这是因为,你将结构体直接以二进制序列方式保存到文件中,也就是说,你将结构体在内存的布局结构直接暴露在文件中。
因为,你在同一个编译器中编译两个程序,并且在同一台计算机上或者相同类型处理器的计算机,是看不出来问题。

不同编译器,对于同一个结构体内部的布局结构是不同的。即使同一个编译器自身设置不同,它也会生成不同布局结构的结构体。

32位程序的编译器与64位程序的编译器生成的结构体布局结构是不同的,因为默认对齐方式不同。

正确的方法应该,将结构体中各个成员,作为单个个体依次分别保存。
并且将各个成员的全部转换为文字型,char 型本身就是文字型所以无须转换。int 等需要转换成相应的字符串数据,然后输出。

并且同一变量中各个字段之间要加特殊的字符作为分割。例如Tab键。
而各条记录之间也需要加特殊的字符作为分割。例如回车键。
这样在保存成TXT文件时,你就可以看到能阅读的数据记录了。否则与int等数字型部分就可能是一串乱码。

在读取文件时,需要转移那两个特殊字符。
可以采用这样的方法,连续读取字符,直到遇到特殊字符,Tab和回车。
之前的多个字符作为一个整体,如果它对应的结构体的成员变量的数据类型是字符型(包括字符串),则验证它是否超过字符型的限制(比如是否超过规定字符串的长度)。如果对应的数值型,则需要专门的函数转换成相应的数值。比如文字型“31”需要转换成数字型“31”。

遇到回车,则表示之前的内容为一条记录(直到上一个回车),则后续将保存到新的记录中。
当然为了保证读取程序的建壮性,你需要能够识别出错误,记录的能力。
比如你的结构体包含四个成员,而某条数据记录只有三个字段,或者某条记录有五个字段。
结构体的成员明明是数字类型,而文件中对应记录的字段却无法正确的转换成数字类型。
同一条记录的各个字段之间有多个Tab,或各条记录之间有多个回车等等。

而读写函数用读取文字型的函数

写函数
int fprintf(FILE *stream, char *format, );
int fputs(char *string, FILE *steam);
int fputc(int ch, FILE *steam);
读函数

int fscanf(FILE *stream, char *format, );
char fgets(char *string, int n, FILE *steam);
int fgetc(FILE *steam);
温馨提示:内容为网友见解,仅供参考
第1个回答  2015-08-08
stu.name类似于指针。追问

?

追答

意思就是你存的是一个地址,而不是数据。读取后,指向的内存不一定有需要的数据。

C语言 fwrite fread 函数怎么使用? 始读取不到数据 也可能我根本没写...
C语言里的fwrite,是带写缓冲的。你往文件里写数据后,数据并不是马上就写到文件里。主要在下面三种情况下会写到文件里:(1)缓冲区满了 (2)使用了fflush函数 (3)使用了fclose函数 所以你的错误就在于,在saveToDisk函数的最后,没有把文件关闭。另外,对文件操作结束,把文件关闭掉本身就是个好...

C语言的fread和fwrite函数剖析,fread后fwrite,内容并没有得到修改_百度...
你好,你这个自定义函数的主要问题是:读取一次就关闭文件了,如果需要再次读取就需要再次打开,但说实话,不主张这种用法,我们一般的用法是全部读取文件的内容但结构体链表或结构体数组中,然后以此判断结构体链表或结构体数组的adder[0].num,判断完之后再次写入文件,这样才可以,你的代码只能判断文件的...

C语言fread函数怎么用啊?为什么我写出来输出数据不对,
C语言中:fread是一个函数。从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功或读到文件末尾返回 0。函数原型:size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;参数:buffer 用于接收数据的内存地址si...

为什么C语言我用fread读入数据会乱码,函数如下
应该是超出数组长度的问题,现在也没有电脑不方便调试代码,你可以自己先检查一下,读取的内容放到了哪里,输出的时候输出的是什么 可以一步一步打印,如果有问题再继续问

c语言fread(p,sizeof(struct stu),1,fp);求大神解答 为啥读取数据时会出...
首先讲下size_t fread(void *buffer,size_t size,size_t count,FILE *stream);虽然这里buffer是个指针,但我们必须给它分配一个缓冲区,不能只定义一个指针p就用它来获取sizeof(struct stu)大小的数据,要知道指针p是个地址,只有四个字节,是放不下那么大的数据的,当然即使放得下也不能这么用...

C语言fread和fwrite问题
随手写的不保证对,只是说明几个问题。1. 你每个文件不管多少只读1K;2. w+ r+是不行的,会把0x0a变成0x0d 0x0a; 3. 你竟然直接返回局部变量 include <stdio.h> include <stdlib.h> include <string.h> define U8 char typedef struct { U8 fileName[9];}Name;\/\/---012345678 define F...

C语言fread()函数读取出问题,求大神解答
fread() 用于2进制文件的读。被读的文件应当是2进制文件,并且是用 fwrite() 写成的。文件打开 必须 用到 "b" (2进制) -- "rb" "wb" ...又读又写文件,注意文件指针位置的控制,般动,回绕文件等等,并保证文件及时写出(调 fflush() )。分别读,写文件,注意文件 关闭,文件打开的顺...

c语言中用fread和fwrite函数读数据时怎样判断文件结束?
使用feof()来判断,返回非0就是结束了。if (feof(fp))... 此时就表明文件结束了,别再读了

c语言文件操作fwrite和fread
fread是C语言标准为中的一个函数。它从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功或读到文件末尾返回 0。fwrite是C语言标准库中的一个函数,指向文件写入一个数据块。示例如下:\/\/读取一个完整的文件#include <stdio.h>#include <...

C语言中指针读写文件,问什么记事本都是乱码,怎么改呢?
从代码看,在Windows平台是有大概率会乱码,假如你的商品信息数组里存放了换行就一定会乱码。主要问题在文件的打开方式不对,fread, fwrite函数最好以二进制模式打开文件,即打开方式加上b,即(rb, wb)。在unix\/Linux系统应该没问题。以下是问题解释:二进制和文本模式的区别 1.在windows系统中,文本...

相似回答