主要内容
- 文件概述
 - 文件指针
 - 文件的打开与关闭
 - 文件的读写
 
文件
把输入和输出的数据以文件的形式保存在计算机的外存储器上,可以确保数据能随时使用,避免反复输入和读取数据
文件概述
- 文件是指一组相关数据的有序集合
 - 文件是存储数据的基本单位,可以通过读取文件访问数据。
 
分类
C语言文件分类
 
缓冲文件系统
 
非缓冲文件系统
文件输入输出函数
文件指针
typedef struct
{    int level;                    //缓冲区“满”或“空”的标志
    unsigned flags;            //文件状态标志
    char fd;                    //文件描述
    unsigned char hold;            //如果没有缓冲区则不读取字符
    int bsize;                    //缓冲区大小
    unsigned char _FAR *buffer; //缓冲区位置
    unsigned char _FAR *curp;    //指向缓冲区当前数据的指针
    unsigned istemp;            //临时文件指示器
    short token;                //用于有效性检查
}FILE;
 
文件的打开与关闭
fopen函数
FILE *fp;
//fp是一个指向FILE结构体类型的指针变量
fp = fopen("file_data.txt","r");
//以只读方式打开文件file_data.txt
 
 fopen函数,会由于无法打开指定文件而出现错误。
如果出错,fopen函数会返回一个空指针值NULL(NULL在stdio.h中被定义为0)。
例如以“r”方式打开时,文件不存在,要进行错误处理。
FILE *fp;
if( (fp = fopen("file_data.txt","r") ) == NULL )
{ printf("can not open the file\n");
exit(0);
}
fclose函数
文件的读写

fputc函数
【例13.1】从键盘输入文本,并将文本写入磁盘上存储的文本文件file_data.txt中。以字符#作为输入结束标志。
分析:
首先打开文件,然后从键盘循环输入字符,如果字符不是结束标志“#”,那么将字符写入文件,否则关闭文件

#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp;
    char ch;
    if( (fp = fopen("file_data.txt","w")) == NULL )  //打开文件
    {    printf("can not open the file\n");
        exit(0);  //退出程序,必须包含<stdlib.h>头文件
    }
    ch = getchar();
    while(ch != '#' )
    {    fputc(ch,fp);  //输出字符
        ch = getchar();
    }
    fclose(fp);  //关闭文件
}
 
fgetc函数
【例13.2】读取文本文件file_data.txt,并将文件中的内容输出到屏幕上。
分析:
首先打开文件,然后反复从文件中读入一个字符,并输出到屏幕,直到文件的结尾,最后关闭文件。

#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp;
    char ch;
    if( (fp = fopen("file_data.txt","r")) == NULL )  //打开文件
    {    printf("can not open the file\n");
        exit(0); //退出程序
    }
    ch = fgetc(fp);  //从文件中读入一个字符
    while(ch != EOF )
    {    putchar(ch);
        ch = fgetc(fp);  //从文件中读入一个字符
    }
    fclose(fp);  //关闭文件
}
 
fputs函数
【例13.3】从键盘输入一串字符串,并将字符串写入文本文件file_data.txt中。
解决该问题的主要步骤为:
(1)打开文本文件file_data.txt。
(2)从键盘输入一串字符串。
(3)将字符串写入文件中。
(5)关闭文件。
(6)结束程序。
#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp;
    char str[20];
    if( (fp = fopen("file_data.txt","w")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
    printf("input the string: ");
    gets(str);
    fputs(str,fp);  //写入字符串
    fclose(fp);
}
 
fgets函数
【例13.4】读取文本文件file_data.txt中指定长度的文本,长度由键盘输入,并将读取的内容输出到屏幕上。
解决该问题的主要步骤为:
(1)打开文本文件file_data.txt。
(2)从键盘输入要读取的文本长度。
(3)读入数据。
(4)输出数据。
(5)关闭文件。
(6)结束程序。
#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp;
    char str[20];
    int n;
    if( (fp = fopen("file_data.txt","r")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
    printf("input the character's number: ");
    scanf("%d",&n);
    fgets(str,n+1,fp);
    printf("%s\n",str);
    fclose(fp);
}
 
fprintf函数
【例13.5】将指定数据写入文本文件file_data.txt中。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp;
    int i=10,j=12;  
    double m=1.5,n=2.345;  
    char s[]="this is a string";  
    char c='\n';  
    if( (fp = fopen("file_data.txt","w")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
    fprintf(fp,"%s%c",s,c);  
    fprintf(fp,"%d %d\n",i,j);  
    fprintf(fp,"%lf %lf\n",m,n);  
    fclose(fp); 
}
 
文件中保存的文本与程序中的数据一致,且格式与指定格式相同
【例13.6】按照每行5个数,将Fibonacci数列的前40个数写入file_data.txt文件中。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp;
    int f[40];
    int i;
    if( (fp = fopen("file_data.txt","w")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
    for (i=0;i<=39;i++)  //求Fibonacci数列
    {    if (i==0||i==1) 
            f[i]=1;
        else
            f[i]=f[i-2]+f[i-1];
    }
 for (i=0;i<=39;i++)  //写入文件
    {    if ((i+1)%5==0)
            fprintf(fp,"%10d\n",f[i]);    
        else
            fprintf(fp,"%10d",f[i]);    
    }
    fclose(fp); 
}
 
fscanf函数
【例13.7】以指定格式读取【例13.5】中生成的文件file_data.txt中的数据,并输出到屏幕上
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp;
    int i,j; 
    double m,n; 
    char s1[100],s2[100],s3[100],s4[100]; 
    if( (fp = fopen("file_data.txt","r")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
 fscanf(fp,"%s%s%s%s",s1,s2,s3,s4); 
//读入四个单词
    fscanf(fp,"%d%d",&i,&j);
 //读入两个整型数据 
    fscanf(fp,"%lf%lf",&m,&n); 
//读入两个double类型数据
    printf("%s %s %s %s\n",s1,s2,s3,s4); 
    printf("%d %d\n",i,j); 
    printf("%lf %lf\n",m,n);
    fclose(fp);
} 
fwrite函数
struct Book_Type
{   char name[10];//书名
  int price;//价格
  char author[10];//作者名
}; 
for(i=0;i<2;i++)
{
  fwrite(&book[i],sizeof(struct Book_Type),1,fp);
} 
【例13.8】通过键盘输入所有2本书的信息,并存储在文本文件file_data.txt中。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{    struct Book_Type
    {     char name[10];//书名
        int price;//价格
        char author[10];//作者名
    };
    FILE *fp;
    struct Book_Type book[2];
    int i;
    if( (fp = fopen("file_data.txt","wb")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
 printf("input the book info: \n");
    for(i=0;i<2;i++)
    {    scanf("%s%d%s",book[i].name,&book[i].price,book[i].author);   
        fwrite(&book[i],sizeof(struct Book_Type),1,fp);   
//读入一条记录
    }
    fclose(fp);
} 
因为是以二进制方式保存,所以记事本中的内容显示为乱码。
fread函数
【例13.9】将【例13.8】中已经存有book信息的文件打开,读出信息后显示在屏幕上。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{    struct Book_Type
    {     char name[10];//书名
        int price;//价格
        char author[10];//作者名
    };
    FILE *fp;
    struct Book_Type book[2];
    int i;
    if( (fp = fopen("file_data.txt","rb")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
 printf("the book info: \n");   
    for(i=0;i<2;i++)
        fread(&book[i],sizeof(struct Book_Type),1,fp);
    for(i=0;i<2;i++)
        printf("name=%s,price=%d,author=%s\n",
  book[i].name,book[i].price,book[i].author);
    fclose(fp);
} 
rewind函数
【例13.10】将指定字符串数据写入文本文件file_data.txt中,并将文件的位置指针重新定位到文件开头,读出文件中的第1个字符数据后显示在屏幕上。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp; 
    char s[]="abcdefghijklmnopqrstuvwxyz";
    char c;
    if( (fp = fopen("file_data.txt","w+")) == NULL )
    {        printf("can not open the file\n");
        exit(0);
    }
    fprintf(fp,"%s",s);  //向文件中写入字符串
    rewind(fp);  //指针返回开始
    fscanf(fp,"%c",&c); //读入一个字符
    printf("The first character is: %c\n",c);
    fclose(fp);
} 
fseek函数

【例13.11】将指定字符串数据写入文本文件file_data.txt中,并将文件的位置指针定位到第5个字符之后,读出第6个字符并显示在屏幕上。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp; 
    char s[]="abcdefghijklmnopqrstuvwxyz";
    char c;
    if( (fp = fopen("file_data.txt","w+")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
    fprintf(fp,"%s",s);
    fseek(fp,5L,0);
    fscanf(fp,"%c",&c);
    printf("The first character is: %c\n",c);
    fclose(fp);
} 
ftell函数
【例13.12】求出文件中包含的字节数。
分析:
先将文件的位置指针移到文件末尾,再通过返回位置指针的位置来取得文件的字节数。
#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp;
    long l;
    if( (fp = fopen("file_data.txt","r")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
    fseek(fp,0L,SEEK_END);   //将文件的位置指针移到文件末尾
    l=ftell(fp);        //返回位置指针的位置
    fclose(fp);
    printf("the length of file is %ld\n",l);
} 
feof函数
【例13.13】判断文件指针是否在文本文件file_data.txt的末尾,并给出相应提示。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp;
    char ch;
    if( (fp = fopen("file_data.txt","r")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
    do
    {    ch=fgetc(fp);
        putchar(ch);
    }while (!feof(fp));   //判断是否到达文件尾
    if(feof(fp)) printf("\nWe have reached end-of-file\n");
//判断是否到达文件尾
    fclose(fp);
} 
ferror函数
【例13.14】判断的文本文件file_data.txt是否有错误,并给出相应提示。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{    FILE *fp;
    if( (fp = fopen("file_data.txt","r")) == NULL )
    {    printf("can not open the file\n");
        exit(0);
    }
    if(ferror(fp))
        printf("Error reading from file_data.txt\n");
    else
        printf("There is no error\n");
    fclose(fp);
} 
                


















