为啥C语言我用fread读入数据会乱码,函数如下

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥C语言我用fread读入数据会乱码,函数如下相关的知识,希望对你有一定的参考价值。

void Material_warehousing()//物资入库的函数 int i, l; FILE *fp; material pur, temp; material *p = &pur; material *p1; if ((fp = fopen("data", "ab+")) == NULL)//打开文件 printf("打开该文件失败!即将关闭程序.\n"); Sleep(3333); exit(1); fseek(fp, 0, 2); p1 = (material*)malloc(ftell(fp)); do printf("请分别输入物资名称、物资购入价格(元)、 物资数量、 采购人:\n"); scanf("%s%lf%d%s", p->name, &p->price, &p->num, p->purchaser); printf("%s%f%d%s\n", p->name, p->price, p->num, p->purchaser); if (p->price < 0 || p->num <= 0) printf("输入错误,请重新输入!\n"); while (p->price < 0 || p->num <= 0); if (ftell(fp) == 0)//若文件中不存在记录 p->code = 1; if (fwrite(p, sizeof(material), 1, fp))//判断是否输出成功 printf("输出成功!\n"); else printf("输出失败!\n"); fclose(fp); else//若文件中存在记录 for (i = 0; i < ftell(fp) / sizeof(material); i++)//读取文件内容到程序中 fread(p1 + i, sizeof(material), 1, fp); fseek(fp, 0, 0); for (i = 0; i < ftell(fp) / sizeof(material); i++)//判断文件中是否存在相同名字的物品 if (strcmp((p1 + i)->name, p->name) == 0) break; fseek(fp, 0, 2); if (i < ftell(fp))//若存在相同名字的物品 (p1 + i)->num = (p1 + i)->num + p->num; l = ftell(fp) / sizeof(material);//要输出的数据结构体的个数 fclose(fp); if ((fp = fopen("data", "wb")) == NULL)//重新创建文件 printf("输出失败!即将关闭程序.\n"); Sleep(3333); exit(1); for (i = 0; i < l; i++) if (fwrite(p1, sizeof(material), 1, fp))//判断是否输出成功 printf("输出成功!\n"); else printf("输出失败!\n"); else//若不存在相同名字的物品 fseek(fp, -76, 2); fread(&temp, sizeof(material), 1, fp);//读取最后一个数据的编号 p->code = temp.code + 1;//这次添加的数据的编号 fseek(fp, 0, 2); if (fwrite(p, sizeof(material), 1, fp))//判断是否输出成功 printf("输出成功!00\n"); else printf("输出失败!\n"); fclose(fp);

参考技术A 应该是超出数组长度的问题,现在也没有电脑不方便调试代码,你可以自己先检查一下,读取的内容放到了哪里,输出的时候输出的是什么
可以一步一步打印,如果有问题再继续问追问

我去看了一下,还是看不出有什么问题。。第一次可以这么正常读出来第二次添加后就乱码了。 能不能帮我看一看

我是新手,也不是很懂

追答

可以

本回答被提问者采纳
参考技术B fread设置缓冲长度时,改为sizeof(material)-1试试

C语言为啥可以重写标准库函数?

就比如printf函数,里面使用了一个输出函数int fputc(int ch,FILE *f),然后就可以直接自己写一个相同名字的int fputc(int ch,FILE *f)函数,只是通过什么形式把数据输出就完全是自己实现的​.函数重名了编译器为什么不会报错?
这个问题我还是自己解决一下吧。这是编译器搞得事情。在MDK软件中使用
__attribute__ ( (weak))
语句就能让一个函数变成弱属性,如果有相同的函数名,但是没有加这个属性的话,就会采用这个函数了,而声明为弱属性的函数就不会被调用

这个问题是一个好问题,我之前也没思索过或者尝试过,
首先我们弄清楚一件事,函数声明可以放在任何头文件,实现可以放在任何实现该函数的源文件中,那么就存在一个问题:
编译时,到底优先去使用哪一个,为什么没有把标准库中的函数扩展过来;在windows下标准库被编译成了msvcr120.dll(msvcr100.dll,这里指release版),所以并不是扩展到代码中,而是在调用时动态链接;
而题主在其中自定义文件中实现了该函数,所以编译时找到了该函数的实现,并不会去链接dll(这应该是编译器做的一些工作,确定系统的dll需要加载哪些),所以题主的程序执行时就只有一份fputc了,并不冲突。
题主可以通过快捷键跳转声明就知道了,VS下,点选fputc实现函数按F12跳转到声明,指向的是stdio.h,再按一次跳转到你自己的定义了。Qt的话使用F2。
大概就是这样子了,可追问。追问

那么我们是不是也可以将一些函数编译成.dll的形式,然后就可以将这些函数进行重写,或者说在源码中还要进行特别申明这些函数可以被重写?

追答

首先说明一点,这个实际上不应该叫重写。
我们也可以将自己写的函数编译成dll,然后另写一个同样的实现函数。
若你在程序中使用到该函数,编译时就会去寻找实现,而在你的源文件中有一份实现,你觉得编译器还会去寻找另外一份实现吗,而且对于动态库,编译时并不会去寻找实现,而是在如动态链接库.lib文件中知道该函数是动态连接及其内存地址。
如你要写与dll中重名的函数,不需要特别声明,只需像通常写函数一样

参考技术A 你看了标准库的源码?追问

没有,只是需要重写一个fputc(),比较好奇。

追答

其实我没太明白你说的意思,能不能举具体代码例子

以上是关于为啥C语言我用fread读入数据会乱码,函数如下的主要内容,如果未能解决你的问题,请参考以下文章

C语言文件输出时,输入数据后为啥会出现乱码

c语言如何将文件数据读入链表?用fread

C语言中fread函数,当文件流缓冲中剩余长度小于需要读取的长度时的问题

c语言读取文件数据乱码

C语言 fread 函数

C 语言文件操作 ( fread 函数 )