前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >结构体存入文件并且取出

结构体存入文件并且取出

作者头像
cloudskyme
发布2018-03-20 11:02:55
9680
发布2018-03-20 11:02:55
举报
文章被收录于专栏:cloudskymecloudskyme

首先定义结构体

代码语言:javascript
复制
struct student_type
{
    char name[10];
    int num;
    int age;
} stud;

 将结构体写入

代码语言:javascript
复制
void save()
{
    FILE *fp;
    int i;
    if((fp=fopen("stu_list","a+"))==NULL)
    {
        printf("canot open the file.");
        exit(0);
    }

    if(fwrite(&stud,sizeof(struct student_type),1,fp)!=1)
    {
        printf("file write error\n");
    }

    fclose(fp);
}

读取文件

代码语言:javascript
复制
void read()
{
    FILE *fp;
    int i;
    if((fp=fopen("stu_list","rb"))==NULL)
    {
        printf("cant open the file");
        exit(0);
    }
    /**
        for(i=0; i<SIZE; i++)
        {
            if(fread(&stud,sizeof(struct student_type),1,fp)!=1)
                printf("file write error\n");
        }
        */

    /**
        while(0 != feof(fp))
        {
            memset(&stud,0,sizeof(stud));
            if(fread(&stud,sizeof(struct student_type),1,fp)!=1)
                printf("file read error\n");

            printf("%s --end >> \n",stud.name);
            printf("%d--end >> \n",stud.num);
            printf("%d --end >> \n",stud.age);
        }
    */

    fseek(fp,0,SEEK_END); //定位到文件末
    int nFileLen = ftell(fp); //文件长度



    int tmpCount = 0;
    int tmpScount = sizeof(stud);
    tmpCount = nFileLen / tmpScount ;

    cout << "file len = " << nFileLen << "   ----   "<<tmpCount<<endl;

    if(tmpCount!=0)
    {
        cout<<"you shuju"<<endl;
        for(i=0; i<tmpCount; i++)
        {
            fseek(fp,tmpScount*i,tmpScount*i);
            cout << tmpScount*i << "  +++++ " <<  tmpScount*i <<endl;
            if(fread(&stud,sizeof(struct student_type),1,fp)!=1)
                printf("file write error\n");

            printf("%s --end >> \n",stud.name);
            printf("%d--end >> \n",stud.num);
            printf("%d --end >> \n",stud.age);
        }
    }
    else
    {
        cout<<"meishuju"<<endl;
    }

    fclose(fp);
}

可以用下面的测试代码

代码语言:javascript
复制

int main()
{
    int i;
    //insert values
    for(i=0; i<10; i++)
    {
        memcpy(&stud.name,"aa",sizeof(stud.name));
        stud.num = i;
        stud.age = i;

        //printf("%s -->> \n",stud.name);
        //printf("%d-->> \n",stud.num);
        //printf("%d -->> \n",stud.age);

        save();//追加写入文件
    }


    //printf("%d -->> \n",sizeof(stud));

    read();

    //printf("getfilesize()=%d\n",getfilesize());


    //read();


    return 0;
}

其中用到的是C语言操作文件的几个方法,特别要提一下的是fseek这个方法

功 能  重定位流(数据流/文件)上的文件内部位置指针

  注意:不是定位文件指针,文件指针指向文件/流。位置指针指向文件内部的字节位置,随着文件的读取会移动,文件指针如果不重新赋值将不会改变指向别的文件。

用 法  int fseek(FILE *stream, long offset, int fromwhere);

描 述  函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0,当前位置1,文件尾2)为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。

返回值  成功,返回0,否则返回其他值。

  fseek position the file(文件) position(位置) pointer(指针) for the file referenced by stream to the byte location calculated by offset.

程序例

代码语言:javascript
复制
  #include <stdio.h> 
  long filesize(FILE *stream); 
  int main(void) 
  { 
  FILE *stream; 
  stream = fopen("MYFILE.TXT", "w+"); 
  fprintf(stream, "This is a test"); 
  printf("Filesize of MYFILE.TXT is %ld bytes\n", filesize(stream)); 
  fclose(stream); 
  return 0; 
  } 
  long filesize(FILE *stream) 
  { 
  long curpos, length; 
  curpos = ftell(stream); 
  fseek(stream, 0L, SEEK_END); 
  length = ftell(stream); 
  fseek(stream, curpos, SEEK_SET); 
  return length; 
  } 
  int fseek( FILE *stream, long offset, int origin ); 

  第一个参数stream为文件指针

  第二个参数offset为偏移量,正数表示正向偏移,负数表示负向偏移

  第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET

  SEEK_SET: 文件开头

  SEEK_CUR: 当前位置

  SEEK_END: 文件结尾

  其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2.

  简言之:

  fseek(fp,100L,0);把fp指针移动到离文件开头100字节处;

  fseek(fp,100L,1);把fp指针移动到离文件当前位置100字节处;

  fseek(fp,-100L,2);把fp指针退回到离文件结尾100字节处。

  使用实例:

代码语言:javascript
复制
  #include <stdio.h> 
  #define N 5 
  typedef struct student { 
  long sno; 
  char name[10]; 
  float score[3]; 
  } STU; 
  void fun(char *filename, STU n) 
  { 
  FILE *fp; 
  fp = fopen(filename, "rb+"); 
  fseek(fp, -1L*sizeof(STU),SEEK_END); 
  fwrite(&n, sizeof(STU), 1, fp); 
  fclose(fp); 
  } 
  void main()/*修改覆盖最后一个学生数据*/ 
  { 
  STU t[N]={ {10001,"MaChao", 91, 92, 77}, {10002,"CaoKai", 75, 60, 88}, 
  {10003,"LiSi", 85, 70, 78}, {10004,"FangFang", 90, 82, 87}, 
  {10005,"ZhangSan", 95, 80, 88}}; 
  STU n={10006,"ZhaoSi", 55, 70, 68}, ss[N]; 
  int i,j; FILE *fp; 
  fp = fopen("student.dat", "wb"); 
  fwrite(t, sizeof(STU), N, fp); 
  fclose(fp); 
  fp = fopen("student.dat", "rb"); 
  fread(ss, sizeof(STU), N, fp); 
  fclose(fp); 
  printf("\nThe original data :\n\n"); 
  for (j=0; j<N; j++) 
  { 
  printf("\nNo: %ld Name: %-8s Scores: ",ss[j].sno, ss[j].name); 
  for (i=0; i<3; i++) printf("%6.2f ", ss[j].score[i]); 
  printf("\n"); 
  } 
  fun("student.dat", n); 
  printf("\nThe data after modifing :\n\n"); 
  fp = fopen("student.dat", "rb"); 
  fread(ss, sizeof(STU), N, fp); 
  fclose(fp); 
  for (j=0; j<N; j++) 
  { 
  printf("\nNo: %ld Name: %-8s Scores: ",ss[j].sno, ss[j].name); 
  for (i=0; i<3; i++) printf("%6.2f ", ss[j].score[i]); 
  printf("\n"); 
  } 
  }

注意事项  fseek函数的文件指针,应该为已经打开的文件。如果没有打开的文件,那么将会出现错误。 fseek函数也可以这样理解,相当于在文件当中定位。这样在读取规律性存储才文件时可以利用其OFFSET偏移量读取文件上任意的内容。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011-01-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档