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);
*/

原文地址:https://www.cnblogs.com/susuzhao/p/2195834.html