C语言中指针读写文件,问什么记事本都是乱码,怎么改呢?

int WriteFile(struct product *head)
{
FILE *fp; //声明fp是指针,用来指向FILE类型的对象
struct product *p=head;//定义一个结构体指针,指向head的地址,也就是链表的头一个结构体
if(head==NULL)
{
printf("文件中数据已为空!\n");
return -1;
}
if((fp=fopen("product.txt","w"))==NULL) //注意这里是打开文本文件用来写入
{
printf("文件打开失败!\n");
return -1;//表示该函数失败;
}
while(p!=NULL) //将链表的全部数据写入文件中
{
fwrite(p,LEN,1,fp); //p指针指向的内容,写入到fp流中,写入记录大小为1个LEN结构的字节大小
p=p->next;
}
fclose(fp); //关闭文件
printf("已将您选择商品功能后的商品的信息成功写入文件!\n");
return 0;
}
struct product *ReadFile(struct product *head)
{
FILE *fp;
struct product *p=NULL;
if((fp=fopen("product.txt","r"))==NULL) //打开文本文件用来读
{
printf("打开文件失败!\n");
return head;
}
p=(struct product *)malloc(LEN);
fread(p,LEN,1,fp);
p->next=NULL;
while(!feof(fp))
{
//下面将从文件读出的一个商品的数据添加到链表的一个节点中

if(head==NULL)
{
head=p;
}
else
{
p->next=head;
head=p;
}
p=(struct product *)malloc(LEN);
fread(p,LEN,1,fp); //从文件中读出一条商品记录到p节点中
p->next=NULL;
}

fclose(fp);//关闭文件
printf("从文件中共成功读出商品的信息\n");
return head;
}

从代码看,在Windows平台是有大概率会乱码,假如你的商品信息数组里存放了换行就一定会乱码。

主要问题在文件的打开方式不对,fread, fwrite函数最好以二进制模式打开文件,即打开方式加上b,即(rb, wb)。在unix/Linux系统应该没问题。以下是问题解释:

二进制和文本模式的区别

1.在windows系统中,文本模式下,文件以""代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"" 。

2.在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。

扩展资料

ffopen为C语言编程中所需的一个常用语言,多数用来打开文件。其调用的一般形式为:文件指针名=fopen(文件名,使用文件方式);其中,‘’文件指针名”必须是被说明为FILE 类型的指针变量,文件名”是被打开文件的文件名;“使用文件方式”是指文件的类型和操作要求。“文件名”是字符串常量或字符串数组。

基本介绍函数功能:打开一个文件函数原型:FILE * fopen(const char * path,const char * mode);相关函数:open,fclose,fopen_s,_wfopenfopen所需库:返回值:文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno 中。一般而言,打开文件后会做一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以一般在fopen()后作错误判断及处理。

参数说明:参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。

mode有下列几种形态字符串:

r 以只读方式打开文件,该文件必须存在。

r+ 以可读写方式打开文件,该文件必须存在。

rb+ 读写打开一个二进制文件,允许读写数据。

rw+ 读写打开一个文本文件,允许读和写。

w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。

w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)

a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)

wb 只写打开或新建一个二进制文件;只允许写数据。

wb+ 读写打开或建立一个二进制文件,允许读和写。ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2022-06-24
先说下错误。
读取,文件是用a+方式打开,这读取数据,因为文件指针在最末的关系,读取出来的数据是空的,所以n永远为0。
其次,在写数据前,没有fclose文件就再fopen一次,这是正确的文件操作方式?
最后,老实说,看你的代码头很痛,不是说代码很难,而是这个格式实在太难看,很多时候,一看到这种混乱的代码,直接看都不看就关掉的。在诸多IDE的今天,写一段格式整齐的代码很难么,不要跟我说你是用windows记事本写代码的。

最最后,下面是整理并修改正确的代码:

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

#ifndef MAX_NUM
#define MAX_NUM 100
#endif

typedef struct student
{
char num[11];
int math;
int eng;
int chin;
int ave;
int totle;
}stu;

void main()
{
stu a[MAX_NUM];
int i = 0, n = 0, k = 0;
FILE *fp = fopen("e:\\student.txt","rb+");
for(n = 0; fp && fread(&a[n], 1, sizeof(stu), fp) != 0; ++n) ;
printf("请输入要添加的信息");
printf("\n请输入第%d个学生信息:\n",n + 1);
printf("学号:\n");
scanf("%s",a[n].num);
printf("math成绩:\n");
scanf("%d",&a[n].math);
printf("english成绩:\n");
scanf("%d",&a[n].eng);
printf("chin成绩:\n");
scanf("%d",&a[n].chin);
a[n].totle=a[n].math+a[n].eng+a[n].chin;
a[n].ave=a[n].totle/3;
for(k = n-1; k >= 0; k--)
{
if(strcmp(a[k].num,a[n].num) == 0)
{
printf("该学生已经存在,请重新输入");
break;
}
}
if(fp == NULL && (fp = fopen("e:\\student.txt","wb")) == NULL)
{
printf("open file error!\n");
exit(0);
}
fseek(fp, 0, SEEK_SET);
for(i = 0; i <= n; i++)
fwrite(&a[i], 1, sizeof(a[0]), fp);
fclose(fp);
}本回答被网友采纳
第2个回答  2021-07-08
你是想让第一个作为帐号,第二个为密码吗fgets你指定了大小100,而且没有那么多字符能读取,所以它把整个文件中的所有字符都读取了,包含空格,gets()也一样

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网