C语言 文件

文件的基本概述

1、二进制文件和ASCII码文件
ASCII文件(文本文件):每一个字节放一个ASCII代码
二进制文件:数据按其在内存中的存储形式原样输出到磁盘上存放
在这里插入图片描述
ASCII文件和二进制文件的比较:ASCII文件便于对字符进行逐个处理,也便于输出字符。但一般占存储空间较多,而且要花费转换时间。二进制文件可以节省外存空间和转换时间,但一个字节并不对应一个字符,不能直接输出字符形式。
一般中间结果数据需要暂时保存在外存上,以后又需要输入内存的,常用二进制文件保存。

2、C语言对文件处理的方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文件类型指针

文件信息有系统定义的名为 FILE 的结构体描述
在这里插入图片描述

FILE *fp;
fp是指向FILE类型结构体的指针变量,可以用fp指向某一文件的结构体变量从而通过该指针访问文件

文本文件操作

1、文件打开函数——fopen

FILE *fp;
fp=fopen(文件名,打开方式);
返回值:成功返回指针,失败返回NULL

在这里插入图片描述
2、文件关闭函数——fclose

fclose(文件指针);
功能:使文件指针与文件脱钩,不在相互联系,无法在用该指针对该文件进行操作
返回值:成功返回0,失败返回EOF(-1)

3、字符读写函数——fputc / fgetc

ch=fgetc(fp);
功能:从指定文件中读出一个字符,该文件必须以读或读写的方式打开
返回值:成功读取字符赋值给ch,遇到结束符则返回EOF
fputc(ch,fp);
功能:将字符写入fp所指向的文件中
返回值:成功返回值就是输出的字符,失败的返回值就是EOF

下面给出几个例子

建立一个文件,并输入一些内容
void main(int argc, char* argv[])
{
    FILE *fp;
    char ch,filename[10];
    scanf("%s",filename);
    if((fp=fopen(filename,"w"))==NULL) 
      { printf("cannot open file\n");exit(0); }
    ch=getchar( );  
    ch=getchar( );  
    while(ch!='#')
          {
            fputc(ch,fp);
            putchar(ch);
	   ch=getchar(); 
	}
     fclose(fp);

}
将以上建立的文件内容进行输出
void main(int argc, char* argv[])
{
    FILE *fp;
    charif((fp=fopen(filename,"w"))==NULL) 
      { printf("cannot open file\n");exit(0); }
    while(!feof(fp))
    {
         ch=fgetc(fp);
         putchar(ch);
     }
     fclose(fp);
}

二进制文件操作

数据块读写 (fread、fwrite)函数

函数调用:
fread (buffer,size,n,fp);
fwrite(buffer,size,n,fp);

参数说明:
buffer:是一个指针。对fread 来说,它是读入数据的存放地址。对fwrite来说,是要输出数据的地址(均指起始地址)。
size:要读写的字节数。
n:要进行读写多少个size字节的数据项。
fp:文件型指针。

例子:将四个学生的的数据的输入和输出
#include <stdio.h>
#define SIZE 4
struct student
{
    char name[8];
    int num;
} stud[SIZE];
void save( )
{
    FILE *fp;
    int i;
    if((fp=fopen("d:\\student","wb"))==NULL)
    {
        printf("cannot open file\n");
        exit(0);
    }
    for(i=0; i<SIZE; i++) /*二进制写*/
        if(fwrite(&stud[i],sizeof(struct student),1,fp)!=1)
            printf("file write error\n");/*出错处理*/
    fclose(fp);
} /*关闭文件*/
void main(int argc, char* argv[])
{
    int i;
    for(i=0; i<SIZE; i++) /*从键盘读入学生信息*/
        scanf("%s%d",stud[i].name,&stud[i].num);
    save( ); /*保存学生信息*/
}
例子:将以上文件进行输出
void list( )
{
    FILE *fp;
    int i;
    if((fp=fopen("d:\\student","rb"))==NULL)
    {
        printf("cannot open file\n");
        exit(0);
    }
    for(i=0; i<SIZE; i++) /*读学生信息*/
        if(fread(&stud[i],sizeof(struct student),1,fp)!=1)
            printf("file write error\n");/*出错处理*/
    for(i=0; i<SIZE; i++) /*显示学生信息*/
        printf("%s%d\n",stud[i].name,stud[i].num);
    fclose(fp); /*关闭文件*/
}
void main(int argc, char* argv[])
{
    list( );
}

文件的定位

1、顺序读写和随机读写
顺序读写:位置指针按字节位置顺序移动。
随机读写:读写完上一个字符(字节)后,并不一定要读写其后续的字符(字节),而可以读些文件中任意位置上所需要的字符(字节)。

2、rewind函数
函数作用:使位置指针重新返回文件的开头,无返回值

例子:有一个磁盘文件,首先将它的内容显示在屏幕上,然后把它复制到另一文件上
#include<stdio.h>
main()
{
    FILE *fp1,*fp2;
    fp1=fopen("file1.c","r");
    fp2=fopen("file2.c","w");
    while(!feof(fp1))
        putchar(fgetc(fp1));
    rewind(fp1);
    while(!feof(fp1))
        fputc(fgetc(fp1),fp2);
    fclose(fp1);
    fclose(fp2);
}

3、fseek函数(一般用于二进制文件)

函数功能:改变文件的位置指针
函数调用形式:fseek(文件类型指针,位移量,起始点)
起始点:
文件开头 SEEK_SET 0
文件当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2
位移量:以起始点为基点,向前移动的字节数。一般要求为long型

fseek函数应用举例
fseek(fp,100L,0);//将位置指针移到离文件头100个字节处
fseek(fp,50L,1);//将位置指针移到离当前位置50个字节处
fseek(fp,50L,2);//将位置指针从文件末尾处向后退10个字节

练习题

在这里插入图片描述
本题注意fgets函数的用法,可一次读取一行
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
int main()
{
    FILE *fp;
    char s[50];
    if((fp=fopen("g:\\data.in","r+"))==NULL)
    {
        printf("can't open file\n");
        exit(0);
    }
    int i;
    while(fgets(s,50,fp)!=NULL)//多行读取,每次可以读取一行,如果遇到结尾返回NULL
    {
        for(i=0; i<strlen(s); i++) //这两种终止循环的方法均可,但是我个人感觉文件中第二个比较好用
        {
            if(s[i]>='A'&&s[i]<='Z')//将大写内容变为小写
            {
                s[i]=(s[i]-'A')+'a';
            }
        }
        printf("%s",s);
    }
    fclose(fp);
    return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    FILE *fp,*read;
    char s[305];
    int i,n,l,num;
    if((fp=fopen("text01.txt","w"))==NULL)//将键盘内容输入文件text01.txt
    {
        printf("can't open file\n");
        exit(1);
    }
    if((read=fopen("text01.txt","r"))==NULL)//将文件text01.txt读出并且输出到屏幕
    {
        printf("can't open file\n");
        exit(1);
    }
    while(scanf("%d ",&n)!=EOF)//此处输入注意吃掉数字后面的空格,否则n的值不会更新
    {
    if(n==0){break;}
    for(i=0;i<n;i++)
    {
        gets(s);
        l=strlen(s);
        fprintf(fp,"%d ",l);
        fputs(s,fp);
        fputc('\n',fp);
        memset(s,0,sizeof(s));
    }
    }
    rewind(fp);//将文件指针指向文件头
    while(fscanf(read,"%d ",&num)!=EOF)
    {
       fgets(s,num,read);
       for(i=0;s[i]!='\0';i++)//因为fgets会保留结尾的换行符,所以用s[i]!='\0'来终止输出
       {
           putchar(s[i]);//此处如果用puts直接输出,puts会直接把'\0'变为'\n',输出会多一个\n;
       }
    }
    fclose(fp);
    fclose(read);
    return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
struct stu
{
    int num;
    char name[21],sex;
    double score[3];
    double avg,sum;
};
int main()
{
    FILE *fp;
    int n,i,l;
    struct stu *s;
    if((fp=fopen("g:\\student.txt","w"))==NULL)
    {
        printf("can't open file!\n");
        exit(1);
    }
    scanf("%d",&n);

        s=(struct stu *)malloc(n*sizeof(struct stu));
        for(i=0; i<n; i++)
        {
            scanf("%d",&s[i].num);
            getchar();
            gets(s[i].name);
            scanf(" %c ",&s[i].sex);
            scanf("%lf%lf%lf",&s[i].score[0],&s[i].score[1],&s[i].score[2]);
            s[i].sum=s[i].score[0]+s[i].score[1]+s[i].score[2];
            s[i].avg=s[i].sum/3.0;
            fprintf(fp,"%d ",s[i].num);
            l=strlen(s[i].name);
            fprintf(fp,"%d ",l);
            fputs(s[i].name,fp);
            fprintf(fp," %c ",s[i].sex);//注意输出格式
            fprintf(fp,"%.2lf %.2lf %.2lf %.2lf %.2lf\n",s[i].score[0],s[i].score[1],s[i].score[2],s[i].avg,s[i].sum);
        }

    fclose(fp);
    return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
struct stu
{
    int num,l;
    char name[21],sex;
    double score[3];
    double avg,sum;
};
int main()
{
    FILE *fp;
    int n,i,l;
    struct stu s;
    if((fp=fopen("g:\\student.txt","r"))==NULL)
    {
        printf("can't open file!\n");
        exit(1);
    }
    while(fscanf(fp,"%d%d ",&s.num,&s.l)!=-1)
    {
        fgets(s.name,s.l+1,fp);//这里注意读取名字的时候要加上'\0'的长度,即+1
        fscanf(fp," %c ",&s.sex);
        fscanf(fp,"%lf%lf%lf%lf%lf",&s.score[0],&s.score[1],&s.score[2],&s.avg,&s.sum);
        printf("%d ",s.num);
        for(i=0; s.name[i]!='\0'; i++)
            putchar(s.name[i]);
        printf(" %c %.2lf %.2lf %.2lf %.2lf %.2lf\n",s.sex,s.score[0],s.score[1],s.score[2],s.avg,s.sum);
    }
    fclose(fp);
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值