C语言初级教程-第10章-文件操作_第1页
C语言初级教程-第10章-文件操作_第2页
C语言初级教程-第10章-文件操作_第3页
C语言初级教程-第10章-文件操作_第4页
C语言初级教程-第10章-文件操作_第5页
已阅读5页,还剩40页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第10章文件操作1I/O设备输入设备键盘、鼠标软盘、硬盘、光驱(以文件的形式)串行口、并行口、USB接口、网络端口扫描仪、视频采集卡、电视卡、游戏杆、话筒……输出设备显示器、打印机软盘、硬盘、CD-R/DVD-R(以文件的形式)串行口、并行口、USB接口、网络端口音箱……单纯的输入设备或者单纯的输出设备越来越少标准输入输出字符界面的操作系统一般都提供标准输入与输出设备DOS、Linux、Unix……一般情况,标准输入就是键盘,标准输出就是终端显示器操作系统有能力重定向标准输入与输出,比如让文件作为标准输入,打印机作为标准输出这种重定向程序本身是感觉不到的自来水厂DOS下的标准输入输出重定向程序prog如下main()

{

charc;

while((c=getchar())!='\n')

putchar(++c);

}输入重定向prog<infile输出重定向prog>outfile流(Stream)计算机中的流的概念一般称为数据流,也有叫做字节流、比特流的,还有很具体的文件流、视频流、音频流等时光不能倒流,但计算机中的很多流都是会倒流的如果你想重新读已经读过的数据,或者要修改已经写入的数据,可以发出流控(FlowControl)命令不会倒流的数据流也很多,例如网络上的数据流。网络和数据线等介质只有很小的数据缓冲区,没有大量存储的能力文件(File)的概念文件一般指存储在外部介质上具有名字(文件名)的一组相关数据的集合用文件可长期保存数据,并实现数据共享程序中的文件在程序运行时由程序在磁盘上建立一个文件,并通过写操作将数据存入该文件;或由程序打开磁盘上的某个已有文件,并通过读操作将文件中的数据读入内存供程序使用文件与流在C语言中,文件可以是磁盘文件、终端显示器或打印机等等。程序通过打开操作把流与设备联系起来,文件打开后,可以在程序和文件之间交换数据。程序通过关闭操作断开流与文件的联系。所有流的性质都一样。因为流与设备无关,所以能写入磁盘文件的同一函数也能写入另一设备,如控制台终端等。但文件的能力则可能不同。例如,磁盘文件可以支持随机存取,而键盘则不行。文件的存放可以建立若干目录(文件夹),在目录里保存文件,同一级目录里保存的文件不能同名。对使用者而言,只要知道文件的路径(全目录)和文件名,就能使用该文件D:\home\Sunner\main.c

这都是托OS的福文件的格式二进制文件是一种字节序列,没有字符变换按照数据在内存中的存储形式存储到文件如整数127,在内存占2个字节,为0000000001111111,则文件中也存储为0000000001111111,占2个字节文本文件/ASCII码文件是一种字符序列文件中存储每个字符的ASCII码如整数127在文件中占3个字节,分别存放这3个字符的ASCII码,即49,50,55文件的格式数据必须按照存入的类型读出,才能恢复其本来面貌公开的标准格式如bmp、tif、gif、jpg和mp3等类型的文件,有大量软件能生成和使用这些类型的文件也有不公开、甚至加密的文件格式如MicrosoftWord的doc格式就不公开,所以至今还没有Word以外的其它软件能完美地读出doc文件int100 float100.0 字符串"100" 字符串"END" 640000

00 C84231303000454E4400

D╚B 10 0 E ND TEST.BIN内容

(十六进制)对应的ASCII字符文件访问文件访问的基本模式open:打开文件,获得对此文件的指针、引用和句柄等,以证明可以使用此文件read:读文件。参数一般指明要读多少字节,读到哪块内存。每次调用此功能,都是接着上次调用的结束位置读。(所以是个输入流)write:写文件。参数一般指明把哪块内存的内容写入文件,要写多少字节。每次调用此功能,都是接着上次调用的结束位置写。(所以是个输出流)close:关闭文件,表明操作结束,不再使用此文件。文件使用完毕必须关闭,否则影响系统性能seek:随机控制流的当前位置,文件定位C语言中的文件访问下面介绍的函数均定义在<io.h>和<fcntl.h>中int

open(const

char*pathname,intaccess);int

fd=open("C:\\CONFIG.SYS",O_RDWR|O_CREAT);pathname是文件名,包含路径。如果不含路径,表示打开当前目录下的文件access是打开方式,常用为O_RDONLY、O_WRONLY、O_RDWR与O_CREAT、O_TRUNC、O_APPEND的位或运算返回值为文件句柄(FileHandle)

,留待以后使用。如果打开失败,返回值为-1C语言中的文件访问int

read(inthandle, void*buf, unsigned

len);int

n_read=read(fd,buf,BUFSIZ);handle是open获得的文件句柄buf是保存读入内容的内存指针len是最大可以读入的字节数返回值为实际读入的字节数,不可能大于len。返回0表示读到了末尾,返回-1表示出错C语言中的文件访问int

write(int

handle,

const

void*buf,

unsigned

len);int

n_write=write(fd,buf,BUFSIZ);handle是open获得的文件句柄buf是要写入内容的内存指针len是写入多少字节返回值为实际写入的字节数,可能小于len。返回-1表示出错C语言中的文件访问int

close(int

handle);intret=close(fd);handle是open获得的文件句柄关闭成功返回0,否则返回-1C语言中的文件访问long

lseek(int

handle,longoffset,

int

fromwhere);intpos=lseek(fd,100L,SEEK_CUR);handle是open获得的文件句柄offset是相对fromwhere的位置偏移多少,可以为负数fromwhere可以是SEEK_SET、SEEK_CUR或SEEK_END中的一个,分别表示文件头、当前位置和文件结尾成功返回移位后的当前位置,从文件头算起;否则返回-1L几个巧妙运用curPos=lseek(fh,0L,SEEK_CUR);fileLength=lseek(fh,0L,SEEK_END);得到文件长度错误处理错误处理文件错误一般都是外界造成的,出错率很高被删除、修改、磁盘空间满、被其他文件打开通过判断返回值发现错误所有文件操作出错时都返回-1出错处理打印错误信息给用户,等待用户的处理voidperror(constchar*s);向标准错误输出字符串s,随后附上错误的文字说明错误处理——例10.1#include<stdio.h>#include<errno.h>#include<io.h>#include<fcntl.h>main(){ /*c:\abc.abc文件并不存在*/

int

fh=open("c:\\abc.abc",O_RDONLY|O_BINARY);

if(fh==-1) /*fh必然为-1*/ {

perror("Can'topenc:\\abc.abc.Error"); }}Can'topenc:\\abc.abc.Error:NosuchfileordirectoryC语言独特的文件访问下面介绍的函数均定义在<stdio.h>中FILE*fopen(const

char*filename,

const

char*mode);FILE*fp=fopen("C:\\CONFIG.SYS",

"rw");filename是文件名,包含路径。如果不含路径,表示打开当前目录下的文件mode是打开方式,常用为"r"、"w"、"rw"和"a",分别表示只读、只写、读写和添加返回值为指向此文件的指针,留待以后使用。如果打开失败,返回值为NULL

mode:对应二进制文件对应文本文件“r”

只读必须是已存在的文件。“w”只写不论该文件是否存在,都新建一个文件。“a”

追加向文本文件尾增加数据,该文件必须存在“r+”读写打开一个已存在的文件,用于读写。

“w+”

读写建立一个新文件,可读可写。“a+”

读写向文件尾追加数据,也可读。

“rb”“wb”“ab”“rb+”“wb+”“ab+”文件指针FILE*fp;是FILE型指针变量标识一个特定的磁盘文件与文件相关联的每个流都有一个FILE类型的控制结构,定义有关文件操作的信息,用户绝对不应修改文件指针(FilePointer)typedef

struct{

shortlevel;/*缓冲区‘满’或‘空’的程度*/

unsignedflags;/*文件状态标志*/

char

fd;/*文件描述符*/

unsignedcharhold;/*如无缓冲区不读字符*/

short

bsize;/*缓冲区的大小*/

unsignedchar*buffer;/*数据缓冲区的位置*/

unsignedchar*curp;/*指针当前的指向*/

unsignedistemp;/*临时文件指示器*/

shorttoken;/*用于有效性检查*/}FILE;在stdio.h文件中定义C语言独特的文件访问int

fgetc(FILE*fp);int

fputc(intc,FILE*fp);char*fgets(char*s,intn,FILE*fp);int

fputs(const

char*s,FILE*fp);int

fscanf(FILE*fp,constchar*format, ...);int

fprintf(FILE*fp,const

char*format,

...);C语言独特的文件访问size_t

fread(void*ptr,

size_tsize,

size_tn,

FILE*fp);size_t

fwrite(const

void*ptr,

size_tsize,

size_tn,

FILE*fp);int

feof(FILE*fp);int

fseek(FILE*fp,

longoffset,

intwhence);int

fclose(FILE*fp);typedefunsignedint

size_t;两种方式的区别open族的功能一般由OS直接提供,其使用方式也比较具有通用性,在各种语言里基本一样fopen族的函数系包装了open族的函数,提供更强大的功能,但是效率略逊open族通常情况能直接反映文件的真实情况,因为它的操作都不假定文件的任何结构fopen族比较适合处理文本文件,或者结构单一的文件。会为了处理的方便而改变一些内容从文件说开去open、read、write、close这种模式成为使用数据流的经典模式比如网络数据流操作就是使用此模式,甚至在一些平台上可以和文件采用完全相同的函数操作seek并不是所有的流都支持网络就不支持对于不能进行流控的流,如果当前数据不立即处理,后来流过的数据就会冲走当前数据,永远不能追回。流控成为流处理中的一个专门技术例如:

fp=fopen(“a1.txt”,”r”);fp=fopen(“d:\\sqs\\a1.txt”,”r”);fopen函数返回指向文件a1.txt的指针并赋给fp,即fp指向文件a1.txt.

若不能实现打开任务,fopen函数将带回一个空指针值NULL(值为0)。常用打开文件的方法为:if((fp=fopen(“a1.txt”,”r”))==NULL){

printf(“cannot

onenthisfile\n”);exit(0);}一、文件的打开:fopen函数二、文件的关闭:fclose函数例如:

fclose(fp);fclose(文件指针);关闭fp所指向的文件。把遗留在缓冲区中的数据写入文件,实施操作系统级的关闭操作。同时,释放与流联系的文件控制块,以后可以再次使用这部分空间。fclose函数的返回值:当顺利地执行了关闭操作,则返回值为0;如果返回值为非零值,则表示关闭时有错误。一般只有驱动器中无盘或盘空间不够时,才失败。关闭失败会引起数据丢失、破坏文件和程序中的随机错误多数情况下,系统限制同时处于打开状态的文件总数,因此,打开文件前先关闭无用文件是必要的ch=fgetc

(fp);

fgetc和

fputc函数fputc

(ch,fp);

---把字符ch写到fp所指向的文件中去。---从指定文件读入一个字符。该文件应以只读或读写方式打开。三、文件的字符读写返回值:若输出成功,则返回输出的字符,否则返回EOF。该文件应以写或读写方式打开。返回值:若输入成功,则返回字符,否则返回EOF。EOF:在stdio.h中定义的常量,表示文件结束#defineEOF(-1)#include"stdio.h"#include"stdlib.h"main(){ charc; FILE*fp; if((fp=fopen("tt.txt","w"))==NULL) { printf("error!\n"); exit(0); } c=getchar(); while(c!=EOF) { fputc(c,fp); c=getchar(); } fclose(fp);}例:将键盘输入的字符顺序存入磁盘文件tt.txt中,输入ctrl+z结束程序运行结果是生成文件tt.txt;#include"stdio.h"#include"stdlib.h"main(){ charc; FILE*fp; if((fp=fopen("tt.txt","r"))==NULL) { printf("error!\n"); exit(0); } c=fgetc(fp); while(c!=EOF) { putchar(c); c=fgetc(fp); } fclose(fp);}例:从文件tt.txt中顺序读取字符并显示出来。四、文件的数据块的读写—fread和fwrite函数

函数调用成功返回count的值,否则返回-1。fwrite()函数的功能:将内存中的一组数据写到fp所指向的文件中。按照内存中的存储形式输出,为二进制文件。fwrite(buff,size,count,fp)所要写入文件的数据在内存中的起始地址写入文件的每个数据项的字节数写入文件的数据项数指向写入文件的指针#include"stdio.h"#include"stdlib.h"typedefstructstudentSTUD;structstudent{ intnum; charname[12];

intscore;};main(){ STUDstu;/*stu为结构体变量*/ FILE*fp; charfilename[12];

int

i,n;

scanf("%s",filename);

if((fp=fopen(filename,"wb"))==NULL) { printf("can'topenthefile!\n"); exit(0); }

scanf("%d",&n);

fwrite(&n,4,1,fp);

for(i=0;i<n;i++) { scanf("%d%s%d",&stu.num,,&stu.score); if(fwrite(&stu,sizeof(STUD),1,fp)!=1)/*写入一个数据项*/ { printf("filewriteerror!"); exit(0); } }

fclose(fp);}例1:文件的数据块写的操作从键盘输入n个同学的学号,姓名和成绩存入文件。#include"stdio.h"#include"stdlib.h"typedefstructstudentSTUD;structstudent{ intnum; charname[12];

intscore;};main(){STUDstu[30];/*stu[30]为结构体数组*/FILE*fp;charfilename[12];

int

i,n;

scanf("%s",filename);

if((fp=fopen(filename,"wb"))==NULL){

printf("can'topenthefile!\n"); exit(0); }

scanf("%d",&n);

fwrite(&n,4,1,fp);

for(i=0;i<n;i++)

scanf("%d%s%d",&stu[i].num,stu[i].name,&stu[i].score);

fwrite(stu,sizeof(STUD),n,

fp);/*一次写入n个数据项*/

fclose(fp);}fread(buff,size,count,fp)fread()函数:功能:从fp所指向的文件中读取一组数据并将其放到内存中去。函数调用成功返回count的值,否则返回-1。待读文件的数据在内存中的起始地址从文件读入的每个数据项的字节数从文件读入的数据项数指向待读文件的指针例2:文件的数据块读的操作#include"stdio.h"#include"stdlib.h"typedefstructstudentSTUD;structstudent{ intnum; charname[12]; intscore;};main(){ STUDstu;/*stu为结构体变量*/ FILE*fp; charfilename[12]; inti,n; scanf("%s",filename); if((fp=fopen(filename,"rb"))==NULL) { printf("can'topenthefile!\n"); exit(0); } fread(&n,4,1,fp); printf("n=%d\n",n); for(i=0;i<n;i++) { if(fread(&stu,sizeof(STUD),1,fp)!=1)/*读入一个数据项*/ { printf("filereaderror!"); exit(0); } printf("%d\t%s\t%d\n",stu.num,,stu.score); } fclose(fp);}#include"stdio.h"#include"stdlib.h"typedefstructstudentSTUD;structstudent{ intnum; charname[12];

intscore;};main(){ STUDstu[20];/*stu为结构体数组*/ FILE*fp; charfilename[12];

int

i,n;

scanf("%s",filename);

if((fp=fopen(filename,"rb"))==NULL) { printf("can'topenthefile!\n"); exit(0); }

fread(&n,4,1,fp);

printf("n=%d\n",n); if(fread(stu,sizeof(STUD),n,fp)!=n)/*读入n个数据项*/ { printf("filereaderror!"); exit(0); }

for(i=0;i<n;i++) {

printf("%d\t%s\t%d\n",stu[i].num,stu[i].name,stu[i].score); }

fclose(fp);}五、文件的格式化读写(文本文件)将输出项arg1,arg2…argn按指定format格式写入fp所指的文件中,即输出到磁盘文件;格式:fprintf(fp,format,arg1,arg2,…,argn);格式:

fscanf(fp,format,&arg1,&arg2,…&argn);

fscanf函数

fprintf函数按指定format格式从fp所指的文件中读取数据依次送入arg1,arg2…argn的内存单元;

arg1,arg2,…argn(&arg1,&arg2,…&argn)输出/输入项表列

format:为格式字符串

fp:为指向fopen函数打开的文件的指针fprintf(fp,“%d,%6.2f”,i,t);将整型变量i和实型变量t的值按%d和%6.2的格式输出到fp指向的文件中。

最好给出长度以保证读写统一fscanf(fp,“%d,%6.2f”,&i,&t);例1:文件的格式化写操作#include"stdio.h"#include"stdlib.h"typedefstructstudentSTUD;structstudent{ intnum; charname[12];

intscore;};main(){ STUDstu;/*stu为结构体变量*/ FILE*fp; charfilename[12];

int

i,n;

scanf("%s",filename);

if((fp=fopen(filename,"w"))==NULL) { printf("can'topenthefile!\n"); exit(0); }

scanf("%d",&n);

fprintf(fp,"%4d",n);

for(i=0;i<n;i++) { scanf("%d%s%d",&stu.num,,&stu.score);

fprintf(fp,"%6d%10s%3d",stu.num,,stu.score); }

fclose(fp);}例2:文件的格式化读操作#incl

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论