结构体中含有指针,并写入文件,该如何读取

mybaobaozhaoyangxing 2015-02-15 11:40:27
从文件中读出一篇英文文章,若干行,每行最多不超过80个字符。首次运行时都不会出错,关闭重新运行就乱了,感觉是指针、分配的内存空间的问题,但是因为不知字符个数多少还是得用到指针。全部贴出来了,能不能帮忙运行一下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <fstream.h>
#define N 100
typedef struct lnode
{
char data;
struct lnode *next;
}Linklist;
Linklist *Par[N];

struct paragraph
{
char *para;//每段写入字符个数不确定,所以用指针,能动态解决这一问题
int count;//每段字符个数
};
struct paragraph *par;
FILE *fp;
int k=0;//记录段数
int i=0;
//存入文件的仅仅是储存链表的数据部分,需要时,从文件中提取数据,重新建立一个新的链表。
//每一段内容由单链表构成,每一个表头结点指向单链表的第一个节点,所有表头结点又组成一个数组

void First()//每次重新运行时,由这个函数能得知已写入文件有几段内容
{
if((fp=fopen("D:\\c\\a.txt","r"))==NULL)
{
printf("没有该文件\n");
return;
}
else
{
fp=fopen("D:\\c\\a.txt","r");
for(i=0;i<N;i++)
{
if(fread(&par[i],sizeof(struct paragraph),1,fp)!=NULL) //这个地方不知如何处理
//if(fread(&par[i].count,sizeof(int),1,fp)!=0)
{
printf("%d ",par[i].count);
k++;
}
else
{
break;
}
}
printf("\n**已存在%d段内容\n",k);
}
fclose(fp);
}
void Write()
{
int n=0;//记录每段字符数
int n1=0;
int n2=0;
int n3=0;
printf("请输入文章:\n");
char c;
Linklist *L;
Linklist *p;
Linklist *s;
L=(Linklist *)malloc(sizeof(Linklist));
while(1)//只要未输入Ctrl+E,即不断输入字符
{
c=getchar();
if(c!=10 && c!=5)//继续写入当前段落的内容
{
n++;
s=(Linklist *)malloc(sizeof(Linklist));
s->data=c;
s->next=NULL;
if(n==1)
{
L->next=s;
Par[k]=L;
}
else
{
p->next=s;
}
p=s;
}
if((c==10||c==5)&& n!=0)
{
n1=n/80;//行数即‘\n’数
n2=n+n1;
n3=n2+5;
par[k].para=(char *)malloc(n3*sizeof(char));
par[k].count=(int)malloc(sizeof(int));
p=Par[k]->next;
for(i=0;i<n2;i++)//将字符传入数组
{
if((i+1)%81==0)
{
par[k].para[i]='\n';
}
else
{
par[k].para[i]=p->data;
p=p->next;
}
}
par[k].count=n;
fp=fopen("D:\\c\\a.txt","a+");
fwrite(&par[k],sizeof(struct paragraph),1,fp);
// fwrite(par[k].para,n2*sizeof(char),1,fp);
// fwrite(&par[k].count,sizeof(int),1,fp);
fprintf(fp,"\n");
fclose(fp);
k++;
n=0;
if(c==5)//Ctrl+E提示文章输入结束
{
printf("文章输入完毕!\n");
break;
}
}
}
}
void Read()
{
int j=0;
int n;
int n1;
int n2;
int n3;
fp=fopen("D:\\c\\a.txt","r");
for(i=0;i<=k;i++)
{
n=par[i].count;
n1=n/80;
n2=n+n1;
n3=n2+5;
fread(&par[k],sizeof(struct paragraph),1,fp);
// fread(par[i].para,n3*sizeof(char),1,fp);
for(j=0;j<n2;j++)
{
if((j+1)%80==0)
{
j++;
}
else
{
printf("%c",par[i].para[j]);//调试时这里会处错误,可能是第二次运行时,第一次分配的空间释放了,不知如何处理
}
}
printf("\n");
}
for(i=0;i<k;i++)
{
printf("%d ",par[i].count);
}
fclose(fp);
printf("\n");
}

void main()
{
par=(struct paragraph *)malloc(N*sizeof(struct paragraph));
First();
printf("写入请按1\n");
printf("读出请按2\n");
printf("退出请按0\n");
int a;
printf("请选择:");
scanf("%d",&a);
while(a!=0)
{
switch(a)
{
case 0:break;
case 1:Write();
break;
case 2:Read();
break;
default:printf("错误!\n");
}
printf("请选择:");
scanf("%d",&a);
}
}


1.写入部分用fwrite(&par[k],sizeof(struct paragraph),1,fp); 读出和first()中用fread(&par[k],sizeof(struct paragraph),1,fp);
未结束时一切都正确,存入文件的是乱码;重新运行时段落k正确,但读出时还是会有错
2.写入部分用fwrite(par[k].para,n2*sizeof(char),1,fp); fwrite(&par[k].count,sizeof(int),1,fp);
读出部分:fread(par[i].para,n3*sizeof(char),1,fp);文件中显示正确字符,关闭重新运行时无论first()函数中如何写,段落k都会出错
...全文
457 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
BrillianceRen 2015-02-15
  • 打赏
  • 举报
回复
你的程序写的一塌糊涂, 本想给你改改, 看了一会果断放弃了.... 给你修改比重新写一个还累, 等晚上有空再说吧
BrillianceRen 2015-02-15
  • 打赏
  • 举报
回复
引用
您好,我还是有些地方不清楚,难道fwrite之后就得将指针free掉,fread的时候再给指针分配空间?这样好像不行啊 我的程序初次运行时没有错误,数据内容感觉都正确的写入文件了,但是关闭后再次运行时,它连par[i].count数值都错了,这是为什么呢?还有如果这时给指针分配空间,感觉也读不出文件里的内容 麻烦你了,谢谢~
1. 运行时数据存放在内存中, malloc, free操作是针对内存的操作, 你创建的局部变量, 全局变量等等都是存放在内存中, 程序重启或者内存掉电都会重新分配内存. 2. fwrite和fread是IO接口, 读写的是存储设备,也就是掉电或者程序重启不会丢失数据的东西. 当你的程序重新启动后, 结构中的para指针指向的数据已经不复存在, 即便你知道你上一次运行程序时的内存地址, 也读不到原来的数据了. 因此需要将数据按可读可写的规则存放在存储设备中, 以备下次使用. 事实上我给出的那个方案真的很简单. 由两部分组成的一条协议, 第一部分是4个字节长度, 存放的是第二部分的长度, 第二部分是不定长的一堆数据. 因为是fread和fwrite是FIFO的, 因此一定要先写第一部分, 再写第二部分. 读的时候先读第一部分, 再读第二部分. 如果这样还不能解释... 我黔驴技穷了.
BrillianceRen 2015-02-15
  • 打赏
  • 举报
回复
首先, 你这个结构体
引用
struct paragraph { char *para;//每段写入字符个数不确定,所以用指针,能动态解决这一问题 int count;//每段字符个数 };
大小为8个字节, 也就是说 sizeof(struct paragraph) 等于8. 这里读出来的count是有效的, para是无效的. 我就说一下简单的存取这个结构的思路. 1. 写
//struct paragraph st = xxx;
fwrite(&st .count, 4, 1, p_file);
fwrite(st.para, st .count, 1, p_file);
2.读
struct paragraph st = {0};
fread(&st.count, 4, 1, p_file);
st.para= (char*)malloc(st.count);
fread(st.para, st.count, 1, p_file);

69,368

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧