C 文件(C语言程序设计教程第三版 谭浩强 张基温著)第八章 文件 读书笔记
以下是 <<C语言程序设计教程>> 第三版 谭浩强 张基温著 第八章 文件 读书笔记
//写一个字符到磁盘文件
// int fputc(int ch,FILE *fp)
//ch 要写入文件的字符,,fp:FILE 类型文件指针
//功能:把字符变量的值输出到指针变量fp所指文件
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
FILE *fp;
int ch;
if((fp=fopen("f:\\file1.txt","w"))==NULL)
{
printf("cannot open this file.\n");
exit(1);
}
while((ch=getchar())!='\n')
{
fputc(ch,fp);
}
fclose(fp);
return 0;
}
//从磁盘文件中读取一个字符
// int fgetc(FILE *fp)
//从指针变量fp 所指文件中读入一个字符
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
FILE *fp;
char ch;
if((fp=fopen("f:\\file1.txt","r"))==NULL)
{
printf("can not open");
exit(1);
}
while((ch=fgetc(fp))!=EOF)
{
//putchar(ch);
fputc(ch,stdout); //等同于putchar(ch);
}
fclose(fp);
return 0;
}
//统计已有文件file1.txt 中的字符个数
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
FILE *fp;
int count=0;
if((fp=fopen("f:\\file1.txt","r"))==NULL)
{
printf("can not open");
exit(1);
}
while(fgetc(fp)!=EOF)
{
count++;
}
fclose(fp);
printf("%d",count);
return 0;
}
// fputs 函数可以向文件写入一个字符串,其原型为 int fputs(const str,FILE *fp);
//参数 str---字符数组或字符串
//把字符数组str中所有字符输出到fp所指文件,但字符串结束符“\0”不输出
//返回:若成功返回非负值,若失败,则返回EOF
//fgets可以从文件读取一个字符串
// char *fgets(char *str,int n,FILE *fp);
//参数: str --- 用于存放读入的字符串
// n ----送入str中的字符个数,包括从文件中读入的n-1个字符和自动添加的“\0”
// 功能:从fp所指文件读取n-1个字符,放到数组str中,如果读入n-1个字符完成之前遇到换行符“\n”或文件结束符EOF,就结束读入,但所遇到的换行符“\n”
// 也作为一个字符送入str数组,在读入的字符串之后自动加一个“\0”
//从键盘输入若干行字符,保存到磁盘上
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
FILE *fp;
char string[81];
if((fp=fopen("f:file2.txt","w"))==NULL)
{
printf("Can not open the file");
exit(1);
}
while(strlen(gets(string))>0)
{
fputs(string,fp);
fputs("\n",fp);
}
fclose(fp);
return 0;
}
//读取字符串
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
FILE *fp;
char string[81];
if((fp=fopen("f:\\file2.txt","r"))==NULL)
{
printf("can not open the file");
exit(1);
}
while((fgets(string,81,fp))!=NULL)
{
printf("%s",string);
}
fclose(fp);
return 0;
}
//利用类似于scanf和printf的 函数fscanf和fprintf进行文件格式化输入输出
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main(void)
{
FILE *fp;
char name[20];
int num;
float score;
if((fp=fopen("f:\\file3.txt","w"))==NULL)
{
printf("can not open the file");
exit(1);
}
printf("type name,num,score:");
scanf("%s %d %f",name,&num,&score);
while(strlen(name)>1)
{
fprintf(fp,"%s %d %f",name,num,score);
printf("type name,num,score:");
scanf("%s %d %f",name,&num,&score);
}
return 0;
}
//C语言中除了可以进行字符,字符串和格式化三种读写之外,ANSI C还对缓冲文件系统做了扩充,允许按“记录”(即数据块)来读写文件,这样方便对程序中的
//数组,结构体进行整体输入/输出。C语言通过fwrite和fread函数进行按“记录”读/写,其调用形式为
// fread(buffer,size,count,fp);
// fwrite(buffer,size,count,fp);
// 参数:buffer一个指针(地址),对于fread而言,它是读入数据的存储区的起始地址;对于fwrite而言,它是将要输出数据的存储区起始地址。
// size ---要读写的字节数(记录的长度)
// count----要读写多少个size字节的数据项,即读写的记录数。
// fp----文件类型指针变量
// 返回:函数fread和fwrite的返回值是实际上已经读入或输出的项数,即执行成功则返回count的值。
// 例如: fwrite(arr,80,3,fp)
// 表示从数组名arr所代表的数组起始地址开始,每次输出80B的数据,共输出3次,即输出240B,输出到fp所指向磁盘文件中,如果执行成功,返回值为3。
// 用函数 fread 和 fwrite实行按“记录”读写,必须采用二进制方式。
//例:通过scanf函数从键盘读入5个学生的数据(包括学生姓名,学号,年龄,三门课程的分数),然后求出每人的平均成绩,用fprintf函数输出学生姓名、
//学号和平均成绩(输出到磁盘文件stud.rec中),再用fscanf函数从stud.rec中读出这些数据并显示在屏幕上。
#include<stdlib.h>
#include<stdio.h>
struct student
{
char name[10];
int num;
int age;
float score[3];
float ave;
}s[5];
int main(void)
{
FILE *fp;
int i;
if((fp=fopen("stud.rec","wb"))==NULL)
{
printf("can not open the file\n");
exit(1);
}
for(i=0;i<5;i++)
{
scanf("%s %d %d %f %f %f",s[i].name,&s[i].num,&s[i].age,&s[i].score[0],&s[i].score[1],&s[i].score[2]);
s[i].ave=(s[i].score[0]+s[i].score[1]+s[i].score[2])/3;
fprintf(fp,"%s %d %f",s[i].name,s[i].num,s[i].ave);
}
fclose(fp);
fp=fopen("stud.rec","rb");
i=0;
while(fscanf(fp,"%s %d %f",s[i].name,&s[i].num,&s[i].ave)!=-1)
i++;
printf("\nName Num Ave\n");
for(i=0;i<5;i++)
{
printf("%-10s %-5d %9.2f\n",s[i].name,s[i].num,s[i].ave);
}
return 0;
}
//文件位置指针定位
// fseek函数:fseek()函数的作用是使位置指针移动到所需位置
// fseek函数原型为: int fseek(FILE *fp,long int offst,int orgn);
//参数:orgn---起始点,可以用数字表示,也可以用stdio.h中所定义的宏来表示
// fseek()中起始点参数
// 参数 宏名 意义
// 0 SEEK_SET 文件头
// 1 SEEK_CUR 当前位置
// 2 SEEK_END 文件尾
// offst为位移量,指以起始点为基点向前移动的字节数,如果其值为负数,表示向后移。所谓“向前"是指从文件开头向文件末尾移动的方向,位移量应为long int
// 型数据,这样当文件长度很长时,位移量仍在long int 型数据表示范围之内。
// fseek(fp,10,0) 将位置指针移动到离文件开始10B处
// fseek(fp,-20,1) 将位置指针从当前位置向后移动20B
// fseek(fp,-50,2) 将位置指针从文件末尾后移50B
// 返回值: 若成功执行,则返回0,若失败,则返回一个非零值。
// ftell函数
// ftell函数能告诉用户位置指针的当前指向,例如 ftell(fp)的值是fp所指文件中位置指针的当前指向,如果出现错误(如不存在此文件),则ftell函数返回值-1,
// 其原型为 long int ftell(FILE *fp);
// rewind函数
// rewind 函数的作用是使位置指针重新返回至文件的开头处,此函数无返回值,其原型为 void rewind(FILE *fp)
// 编写一个程序,将磁盘文件1的内容复制到磁盘文件2中,即模仿copy命令的功能。
#include<stdio.h>
#include<stdlib.h>
char buff[32768];
int main(int argc,char *argv[])
{
FILE *fp1,*fp2;
unsigned int bfsz=32768;
unsigned long i=0;
if((fp1=fopen(argv[1],"rb"))==NULL)
{
printf("can not open the file %s",argv[1]);
exit(1);
}
if((fp2=fopen(argv[2],"wb"))==NULL)
{
printf("can not open the file %s",argv[2]);
exit(1);
}
while(bfsz)
{
if(fread(buff,bfsz,1,fp1))
{
fwrite(buff,bfsz,1,fp2);
i=i+bfsz;
}
else
{
fseek(fp1,i,0);
bfsz=bfsz/2;
}
}
fclose(fp1);
fclose(fp2);
return 0;
}
/*
大多数标准I/O函数并不具有明确的出错信息返回值,例如:如果调用fputc函数返回EOF,他可能表示文件结束,也可能是因调用失败而出错了,
ANSI C 为此提供了专门函数来处理I/O调用中的错误。
ferror 函数可明确检查是否出错,int ferror(FILE *strm);
在调用fopen函数时,会自动使相应文件ferror函数的初值为零,如果函数返回值为0,则表示没有出错,如果返回值非零,则出错。
当一个程序中要多次使用I/O调用时,应在每调用一次输入/输出函数后,都有一个ferror函数值与之对应,并在调用后立即测试ferror 函数的值,否则该值会丢失。
因为ferror反映的是最后一个函数调用的出错状态。
fclearerr函数
函数fclearerr()作用是重置ferror函数的初值为零,使用目的是为了在一次监视I/O调用并测试使用ferror()的值后,立即使其复位,以便有效监视下一个I/O调用
fclearerr()原型为 int fclearerr(FILE *strm);
*/