C语言:文件存取.pdf

上传人:索**** 文档编号:76242582 上传时间:2023-03-08 格式:PDF 页数:12 大小:36.83KB
返回 下载 相关 举报
C语言:文件存取.pdf_第1页
第1页 / 共12页
C语言:文件存取.pdf_第2页
第2页 / 共12页
点击查看更多>>
资源描述

《C语言:文件存取.pdf》由会员分享,可在线阅读,更多相关《C语言:文件存取.pdf(12页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、C语言:文件存取初步在磁盘上数据的存储是以OS文件为单位的。OS文件可分为两大类:文本(Text)文件和二进制(Binary)文件。Text 文件可以在屏幕上或打印机上打印(例如在某个Text Editor中打开),是肉眼可读的;而二进制文件,如果也在Text Editor中打开,你看到的可能一片“乱码”。其实,任何文件在磁盘上,存储的都是二进制代码,以字节为单位,每一字节由 8 个二进制位(0 或 1)组成。因此,C 语言统称它为字节流(Byte Stream)。如果说两者有区别,区别在于,对于ASCII 文本文件,每一个字节中的二进制码恰好代表一个ASCII 字符,而且,因为文本文件一般是

2、用于显示或打印的目的,字节流被分成一系列“行”,每一行以回车符和换行符(r n)结尾;而二进制文件,每个字节的二进制码可能不对应于任何可印刷字符,也没有“行”的概念。在 C语言中,这两种文件都可通过文件I/O 库函数(也称流函数)存取(读写)。为了使用键盘输入、屏幕输出和打印机输出,C 语言(以及 DOS)把这些设备也视为文件,称为设备文件。于是,C程序可以用同样的文件I/O(输入输出)函数存取磁盘文件和设备文件。在 stdio.h文件中列出了所有ANSI C 标准文件 I/O 库函数原型及其用到的数据结构的定义。其中,最重要的数据结构是FILE 结构体:FILE 结构体:typedef st

3、ruct short level;/*fill/empty level of buffer*/unsigned flags;/*File status flags */char fd;/*File descriptor */unsigned char hold;/*Ungetc char if no buffer*/short bsize;/*Buffer size */unsigned char *buffer;/*Data transfer buffer*/unsigned char *curp;/*Current active pointer*/unsigned istemp;/*Tem

4、porary file indicator*/short token;/*Used for validity checking*/FILE;任何文件在读写前必须打开。文件标准I/O 是使用缓冲区的。当用fopen()打开一个文件时,存取该文件用的缓冲区在内存中被fopen()建立,fopen()也同时建立一个与存取该文件有关的FILE 结构体,并返回指向该 FILE 结构体的指针。注意,在这个FILE 结构体中,指针变量buffer正是指向所建缓冲区的指针。FILE 结构体还包含与存取该文件有关的信息,当文件在读写过程中,有些信息也在相应地更新。例如,curp 指针总是指向缓冲区中当前要读写的

5、位置。你无须了解FILE 结构体的每一成员的细节,你一般也用不着直接访问FILE 结构体中的成员变量,你只须知道 fopen()返回的 FILE 指针是与所打开的文件相联系的,或者说得简单些,这个FILE 指针指向的就是所打开的文件(虽然实际指向的是与所打开的文件相联系的FILE 结构体)。随后,当用其他标准I/O 函数读或写文件时,你只是简单地引用FILE 指针,以便告诉C,你要读写的是那一个文件。用来读写已打开文件的标准I/O 函数主要包括:fgetc():读单个字符,fgets():读 n 个字符,fputc():写单个字符,fputs():写一字符串。fscanf():读一字符序列,并

6、按接收变量的类型转换。fprintf():把输出变量的内容转换成字符序列,写到文件上。fread():读 n 个字节,fwrite():写 n 个字节。(常用于读写二进制文件)rewind(),fseek():移动文件当前读写位置,ftell():返回文件当前读写位置还要记住,读写结束后,应当用fclose()关闭所打开的文件,以确保缓冲区的内容被写到文件上。标准(ANSI C)输入输出函数:打开文件:FILE *fopen(const char*path,const char*mode);其中,path 字符串指定要打开的文件名,如“C:Dir1File1.txt”;mode字符串指定对该文

7、件的存取方式,如“r”。mode 字符串可以是以下字符的组合:r(读),w(写),a(追加),+(读和写),t(文本方式),b(二进制方式)如果不指定t 或 b,则默认为 t;如果有 r 或 a,则文件必须已存在;如果w,则当文件存在时,清除原内容后再写,否则创建新文件。a 与 w 不同,它不清除原内容,而是在原内容之后补写。+和 r、w、或 a 连用,容许读和写,是否要求原文件存在或是否创建新文件,取决于r、w或 a。fopen()函数返回 FILE 指针,你用 FILE 指针变量(以下为叙述方便,设为Fp)接收这个返回值,随后在用其他I/O 函数读写该文件时,要引用这个FILE 指针变量

8、Fp。或者粗略地说,Fp 就是这个 fopen()打开的、随后要读写的文件。如果打开不成功,fopen()返回 NULL,NULL在 stdio.h 中被#define为整数 0)。例:FILE*Fp;Fp=fopen(“C:Dir1File1.txt”,“r”);/*为读打开,Text 方式 */Fp=fopen(“C:Dir1File1.txt”,“r+”);/*为读写打开,r 要求文件必须存在,Text 方式 */Fp=fopen(“C:Dir1File1.txt”,“wb+”);/*为读写打开,Binary 方式 */fprintf(Fp,“%d,%d,%d”,i,j,k);/*往打开

9、的 Fp 文件上写 */关于文件当前位置指针:所有 I/O 函数都维护文件读写的当前位置指针。当fopen()打开文件成功时,当前位置指针指向文件的开始处(第一个字节)。随后,你可顺序读或写文件。所有执行读或写功能的函数(见后),在读或写 n 个字节后(n=1),当前位置指针均移动n 个字节,即指针自动移动到下一次要读或写的位置(当然不会超过文件尾)。以下在介绍每个函数时,不再特别说明。你也能调用rewind()、fseek()、fsetpos()等函数重置当前位置指针后再读写(所谓“随机读写”)。请勿将文件读写的当前位置指针与FILE 指针、及 FILE 结构体中的buffer指针相混。读写

10、方式:文本方式与二进制方式任何文件都可以以文本方式或二进制方式打开。两者在读写文件时的区别是:文本方式:当写文件时,如果被写的内存字节是0 x0D(r ),它被照写不变,但若是0 x0A(n )则写两个字节0 x0D 0 x0A(r n )到文件上。反之,当读文件时,凡遇到0 x0D 时即 r 时就跳过不计,自动移到下一字节(直到非r ),而 0 x0A(n )照读不误。这也顺便说明了为什么printf()遇到 n 时不仅在屏幕上换行(n )而且也回车(这是 r 的功能)。二进制方式:与文本方式不同,写时即不转换n ,读时也不滤掉r ,任何字节都原封不动地写入文件或读到内存。虽然任何文件的读写

11、方式都可在fopen()时任意指定,但习惯上,一般用文本方式读写文本文件,即 ASCII.txt文件,而用二进制方式读写其他文件。顺便指出,字节 和字符(ASCII)在文件 I/O 中是一个意思,当说字符时,实际也是指存放该字符的 8-bit字节,或该字符的8-bit编码。只是,当处理文本文件时,人们习惯用“字符”,而处理二进制文件时,习惯用术语“字节”。标准设备文件:任何 TurboC 程序开始运行时,都自动打开了5 个设备文件,这5 个 FILE 指针变量名(系统变量)是:stdin标准输入(键盘)文件stdout标准输出(屏幕)文件stderr标准出错输出(屏幕)文件stdprn标准打印

12、(打印机)文件stdaux标准辅助输入输出(串口)文件于是,为了读或写上述某文件,你只须直接引用相应的FILE 指针变量名(代替Fp)。关闭文件:int fclose(FILE*Fp);本函数关闭已打开的文件Fp,如果关闭成功,本函数返回0,否则返回一个非零值(-1)。关闭 意味着:a)释放该文件打开时建立的I/0缓冲区,如果在缓冲区中尚有未写入文件中的数据,在释放前,先写入文件。B)Fp 文件关闭后不能再读写,Fp 指向的 FILE 结构体所占的内存空间也被释放,Fp 置成 NULL。以下介绍主要的读写函数,并以例说明它们的用法。写一个字符(字节):int fputc(int c,FILE*

13、Fp);该函数把 int变量 c 的低 8 位(也可是 char 变量)写到Fp文件的当前位置。该函数的返回值是c 的值或 EOF,EOF表示写操作不成功。另外,宏 putc(c,fp)也能用来写字符c,而#define putchar(c)putc(c),stdout)注意,函数fputc(c,Fp)或 putc(c,Fp)只是写单个字符或字节到文件的当前位置,写完后当前位置自动移动到文件的下一字节位置。于是,你可连续地用这个函数把一串字节顺序写到文件上。读一个字符(字节):int fgetc(FILE*Fp);该函数返回Fp文件当前位置上的那个字节(作为 int类型返回值的低8 位)。如果

14、当前位置是EOF (文件尾),则返回 EOF(stdio.h中定义 EOF为 1)。如果用此函数顺序读ASCII 文件,你可判断返回值是不是EOF而知文件是否读完(ASCII 字符的编码是 0-127,不可能是-1)。但若读非 ASCII 文件,值-1 可能是文件的正文内容,并不一定意味着文件尾。因此,你不能用上述方法判断文件是否读完。但在任何情形,你都能用FILE 结构体中的flags值的第 6 位(从右数)是否为1 知道当前位置是否在文件尾。等价地,你也可以用宏feof(Fp)来判断:feof(Fp)=1意味着 Fp 文件当前在文件尾。此外,文件读写时也可能出错,你可用flags值的第 5

15、 位或 ferror(Fp)宏判断。即在任何I/O 操作之后,若 ferror(Fp)为 1(真),则表示出错。顺便指出,宏getc(Fp)同效于 fgetc(Fp),但 getc(Fp)的值是char型的,而 getchar()定义为:#define getchar()getc(stdin)类似于 fgetc(c,Fp)写的是单个字符,本函数也只是从文件上读单个字符(或字节),如果想读完整个文件,你必须在打开文件后连续地使用本函数,直至文件尾。因为每读一个字符后,文件的当前位置指针自动加1,下一次再读时读的肯定是下一字符,所以你不必自己去移动当前位置指针。例文件:Students.txt 姓

16、名系别性 身高出生入学0 1 2 3 4 012345678901234567890123456789012345678901234-Zhang Hai Math Dept F 1.86 19730826 19970915 Wang Jun Math Dept F 1.81 19650921 19960131 Zhou Ling Math Dept M 1.61 19740301 19970915 整个文件内容,共 5 行Wang Jing Math Dept F 1.75 19720521 19960214 Zhang Yun Math Dept M 1.71 19740911 199709

17、15 -每行 45 个正文字符加上2 个字符(rn)。整个文件5 行,共 47x5=235 字符,或 233,最后可能无回车和换行符,依赖于写文件是是否写它们。注意,数据之间用一个空格符分界。在以下每一例的程序中,应包含下述语句(例中不再写出):#include FILE*fp;Char FileName20=“Students.txt”;例 1.用 fputc()函数创建Students.txt文件:#include /*For strcat()*/main()char StArr547=Zhang Hai Math Dept F 1.86 19730826 19970915n,Wang J

18、un Math Dept F 1.81 19650921 19960131n,Zhou Ling Math Dept M 1.61 19740301 19970915n,Wang Jing Math Dept F 1.75 19720521 19960214n,Zhang Yun Math Dept M 1.71 19740911 19970915n ;/*Note:AtArri45=n ,StArri46=0 (初始化时自动补 0)*/int i,k;char c;fp=fopen(FileName,“w”);/*建新文件,Text mode*/*如果 Binary mode“wb”,初值中

19、的 n 应当换成 rn,StArr548。其他语句均不变。*/if(fp=NULL)printf(Cannot create the new file.n);exit(0);for(i=0;i5;i+)for(k=0;(c=StArrik)!=0;k+)fputc(c,fp);/*写 StArrik*/if(fclose(fp)!=0)/*关闭文件,成功时为0*/printf(Cannot close the file.n);else printf(“n%s”,strcat(FileName,was created.);例 2.用 fgetc()函数读 Students.txt文件:本例把 S

20、tudents.txt文件的第 i 行(以n 结尾)读到 StArr数组的第 i 行 StArri中,且补 0 。main()char StArr10050;int i,k;char c;fp=fopen(FileName,“r”);/*读文件,Text mode*/*在 Text mode,文件中的 rn读成 n*/*如果 Binary mode“rb”,文件中任何字符均不变地被读入。*/i=0;k=0;while (c=fgetc(fp)!=EOF&i100)StArrik=c;/*读入 StArrik*/k+;if(c=n)StArrik=0;i+;k=0;/*行尾补 0*/fclose

21、(fp);/*关闭文件*/写一串字符(字节):int fputs(char*s,FILE*Fp);该函数把以 0 结尾的字符串s 写到Fp文件中,从当前位置开始。但最后的0 不写。写成功时返回写入的最后字符,出错时返回EOF。读一串字符(字节):char*fgets(char*s,int n,FILE*Fp);该函数把Fp文件当前位置开始的(至多)n-1 个字符读到字符数组s 中,如果遇到r ,则跳过不计它。但若遇到n ,即使还不到n-1 个,则在把 n 读到 s 中后,也不再读了。最后在s 中补上 0 后,fgets()返回,返回值也是指向s 的指针。如果在上述读的过程中,发生错误或先遇到文

22、件尾,则返回NULL 此时你须用 feof(Fp)或 ferror(Fp)才能判断是遇到文件尾还是出错。例 3.用 fputs()函数创建Students.txt文件:main()char StArr547=。;/*初始化同例1*/int i;fp=fopen(FileName,“w”);/*建新文件,Text mode*/*如果 Binary mode“wb”,初值中的 n 应当换成 rn,StArr548。其他语句均不变。*/for(i=0;i5;i+)fputs(StArri,fp);/*写 StArri*/fclose(fp)/*关闭文件*/例 4.用 fgets()函数读 Stude

23、nts.txt文件:char StArr10050;fp=fopen(FileName,“r”);/*读文件,Text mode*/i=0;while(fgets(StArri,50,fp)!=NULL&i=1。每一个结构体相当于一个“记录”。用 fwrite()写到文件上的数据通常可以用fread()读回来。例 5.用 fwrite()函数创建Students.dat文件(Binary):Students.txt是 ASCII 文件,但在程序中,学生的身高通常用浮点数 类型,以便用于计算,如计算学生的平均身高等。显然,用Struct类型来描述学生的信息是合理的。我们将从 Students.t

24、xt文件读出学生信息,并把字符形式的身高转换为float形式。然后,再用 fwrite()输出,创建 Students.dat二进制文件。最后再用fread()读出,并 check 结果。#include /*double atof(char*)*/#include /*strcpy(char*,char*)*/#include FILE*fp;char FileName120=Students.txt;char FileName220=Students.dat;struct STUD char StName11,DeptName10;char Sex;float Height;char Bo

25、rnDate9,EntryDate9;typedef struct STUD STUDENT;main()STUDENT St100;char SS50;int i,n;extern STUDENT*ssTOst(char*,STUDENT*);fp=fopen(FileName1,r);n=0;while(fgets(SS,50,fp)!=NULL&n100)/*读.txt文件*/ssTOst(SS,&Stn);n+;/*转换成 STUDENT 结构体 */fclose(fp);/*txt文件共n行*/fp=fopen(FileName2,w+b);/*Create Open in Bina

26、ry R/W mode*/fwrite(St,sizeof(STUDENT),n,fp);/*写 St 到 Binary File,用 sizeop(struct)*/fflush(fp);/*清 buffer*/rewind(fp);/*point to top*/fread(St,sizeof(STUDENT),n,fp);/*读 Binary File 到 St*/fclose(fp);for(i=0;i n;i+)/*check读后结果:*/printf(%s%s%c%4.2f%s%sn,Sti.StName,Sti.DeptName,Sti.Sex,Sti.Height,Sti.Bo

27、rnDate,Sti.EntryDate);/*end of main()*/char*substr(char*dest,char*str,int begin,int n)/*截取 str的子串 */int i;char c;begin=begin-1;for(i=0;iStName,substr(s1,ss,1,10);strcpy(st-DeptName,substr(s1,ss,12,9);st-Sex=ss21;st-Height=(float)atof(substr(s1,ss,24,4);/*数字串=数*/strcpy(st-BornDate,substr(s1,ss,29,8);

28、strcpy(st-EntryDate,substr(s1,ss,38,8);return st;/*end of program*/格式化写 (以字符格式写n 个表达式的值):int fprintf(FILE*Fp,const char*format,expr1,expr2,.);完全象用 printf()屏幕输出那样,你可用fprintf()把同样的数据写到任何文件上。Expr1,expr2 等先按 format 指示转换成字符序列,然后再写到Fp 文件上。注意,%s格式写出的字符串,不写结尾的 0 ,其他字符都写,包括r 和 n (而且当用Text 方式时,n 写成 r n )。在写完所

29、有转换出的字符序列之后,最后再自动补写一个n (binary方式),或补写 r n(Text 方式)。本函数的返回值是实际写入文件的字符个数。注:当 Fp 是 stdout时,fprintf(stdout,)和 printf()(不是宏)有相同的功能。格式化读:int fscanf(FILE*Fp,const char*format,addr1,addr2,.);本函数是 scanf()函数的翻版,它可适用于从任何文件Fp 上读字符序列,并按format转换类型后存入地址 addr1,addr2,.。值得注意的是,当用%s读字符串时,只要遇到(空格)、n 、t 、r (仅在 binary方式下

30、。因在Text 方式,r 是被滤掉的)或0 字符,就认为字符串结束(这个字符也不放入接收地址),然后再补放0 。%d等数值格式,则会滤掉前面的非数字字符,并在遇到非数字字符时认为数结束。于是,当用fprintf()把一些变量写到文件上后,可能无法再用fscanf()读回到这些变量中来,特别是%s和其他格式混用时。本函数的返回值是实际读入值的变量个数。清除缓冲区:int fflush(FILE*Fp);清除 Fp 的缓冲区。如果是写文件,则先写回到磁盘后再清。当前读写位置重指文件头:int rewind(FILE*Fp);本函数置 Fp 文件的当前读写位置为文件的的首字节,相当于刚fopen()

31、的位置。附:其他常用函数:long ftell(FILE*Fp);本函数返回Fp 文件的当前读写位置(用距离文件头的offset表示)。如果有错,返回 1L。int fgetpos(FILE*Fp,long*pos);本函数把 Fp 文件的当前读写位置赋值给*pos。函数返回值是0,如果有错,返回非0 值。int fsetpos(FILE*Fp,const long*pos);本函数置 Fp 文件的当前读写位置为*pos。函数返回值是0,如果有错,返回非0 值。int fseek(FILE*stream,long n,int whence);其中,whence 可以是 0,1,或 2,分别代表

32、文件头、当前读写位置、和文件尾。本函数置 Fp 文件的当前读写位置为离whence有 n 个字节。n可为负值,正表示向后(向文件尾方向),负表示向前。注:有了上述函数,你便可实现随机读写功能:定位后再用前述的读写函数顺序读写。但要注意,为使用 fsetpos()函数,应当先用ftell()或 fgetpos()函数保存文件读写位置。int flushall(void);清除所有打开文件的缓冲区。void setbuf(FILE*Fp,char*b);指定字符数组b 为 Fp 的缓冲区,代替 Fp 打开时建立的缓冲区。数组 b 的大小不应小于stdio.h中定义的 BUFSIZ常数(原为512)

33、。若 Fp 为 NULL,则 Fp 文件的读写将不使用缓冲区,直接在程序数据区(如变量)和文件之间交换数据。int setvbuf(FILE*Fp,char*b,int type,long size);也是另建缓冲区,但这个缓冲区是由本函数动态建立的,大小为size,指针 b 将指向这个缓冲区。type=0,1,或 2,分别表示全缓冲、行缓冲和不用缓冲区。char*strerror(int n);返回 Err No.为n时的 Err Msg。在 stdlib.h中定义了 int变量 errno。每当 I/O 函数发生错误时会把错误代号送到errno 变量中。void perror(const

34、char*UserMsg);在 stderr文件上输出UserMsg,然后冒号,然后再输出对应于 errno 变量值(错误代号)的Err Msg,最后输出 n 。void clearerr(FILE*Fp);清 Fp 文件的 FILE 结构体中 flags的出错位和EOF位(第 5 和 6 位置 0)。FILE*tmpfile(void);建立并以 Binary 方式打开一个临时文件,如果成功则返回指向该文件的 FILE指针,不成功则返回NULL。char*tmpnam(char*s);返回一个具有唯一性的文件名(也放到s 数组中)。int rename(const char*oldname,

35、const char*newname);文件重命名,成功则返回0。int unlink(const char*filename);删除所指定的文件。#define remove(path)unlink(path)删除所指定的文件。int ungetc(int c,FILE*Fp);在用 getc 读文件后,可用ungetc()“退回”(接着再 getc()时,仍读入字符c)。本函数的返回值也是字符c(整数),不成功则返回EOF(-1)。int getw(FILE*Fp);从 Fp 文件中读一整数(2 个字节),且作为本函数的返回值。int putw(int w,FILE*Fp);将整数w所占的

36、 2 个字节写入Fp 文件。此外 TurboC 还提供了若干非ANSI C 的 I/O 函数 -更低层的 I/O 函数,见 io.h文件。C 语言复习提纲总要求:要求学生在课程结束后,能 *掌握通用高级程序设计语言中的基本概念:数据类型,变量(数组)声明,变量作用域程序中的三种结构:顺序,选择,循环数制,数的存储表示,二进制原码、反码与补码,浮点数存储格式函数与过程,参数传递机制 *较熟练地使用循环语句和函数完成简单程序的C 程序设计数据类型、变量和表达式:数据类型:整数,实数,字符数的存储表示:二进制数的原码、反码与补码整数、小数和字符的存储表示C 语言中常数的表示数制:十进制,八进制,二进

37、制,十六进制;ASCII 字符集变量声明和变量初始化,标识符,常量定义(#define)算术表达式,二进制位运算关系表达式,逻辑值,逻辑表达式,条件表达式;程序结构:顺序结构:表达式语句,赋值语句,空语句,复合语句(分程序)选择结构:If 语句,Switch 语句循环结构:While,Do-While,For 语句;Break,Continue 语句转移控制:语句标号与Goto 语句结构化程序设计的概念模块化,自顶向下分解,黑盒,公用变量/局部变量/参数,Goto 问题数组:数组:概念,一维和二维数组的声明与使用用字符数组处理字符串,常用的字符串函数函数:函数声明、函数定义与函数调用,参数传递

38、,递归调用,return语句C 程序文件的结构Main(),自定义函数,库函数,函数原型,#include 指示变量的存储类型与作用域,函数的作用域宏定义(#define)与宏展开指针:指针变量的作用,指针变量声明与用法指针与数组,用指针变量处理字符串传址参数的实现结构数据类型:结构体(Struct):类型、变量、数组、指针,sizeof expression,sizeof(数据类型)联合(Union)和 枚举(Enum)类型类型重定义(typedef)文件存取:文件的打开与关闭,读与写。附 1:C语言运算符的优先级由上至下,优先级由高到低。同一行上的运算符有相同的优先级,除“单目”、“条件”

39、、“赋值”这三行是由右向左结合外,其他都是由左向右结合。可用圆括号结合或提高优先级。().-单目 !(非)(求反)-(负)+-&(地址)*(指针)(type)sizeof 算术*/%+-移位 比较 =!=位运算&(按位与)(按位加)|(按位或)逻辑&(逻辑与)|(逻辑或)条件?:赋值 =+=-=*=/=%=&=|=逗号 ,注:单目运算符sizeof产生整数值,表示其后运算对象在内存中占的字节数:sizeof(x)x可以是类型名、变量名、数组名附 2:main()函数可有参数整个 C 程序可通过 main()函数获得由执行它的DOS命令行所提供的参数。此时,main()函数可有两个形参:main

40、(int argc;char*argv)其中 argv是数组,有argc 个元素,每个元素是char 指针,即指向一字符串(字符数组)的指针。当启动本 C 程序(如 Prog1.exe)的命令行是 PROG1.EXE PARA1,PARA2,PARAn-1时,argc 的值将是整数n,而 argv0 是字符串“PROG1.EXE”,即程序文件名。argv1 是字符串“PARA1”,argv2 是“PARA2”,argvn-1 是“PARAn-1”。例 1:以下程序将输出每一个命令行参数(字符串):main(int argc;char*argv)int i;for(i=1;iargc;i+)pr

41、intf(“%sn”,argvi);/*输出:PARA1 PARA2 ,PARAn-1 */例 2:以下程序zcopy.c(不包含出错处理语句)可用来拷贝文件:#include main()FILE*fp1,*fp2;char c;fp1=fopen(argv1,rb);fp2=fopen(argv2,wb);/*binary mode*/while(1)c=fgetc(fp1);if(feof(fp1)break;fputc(c,fp2);fclose(fp1);fclose(fp2);命令行 是 zcopy.exe from-file to-file.例如 zcopy.exe studen

42、ts.txt stcopy.txt课程实习 1:打印月历题目要求:给定年份和月份,把该月的日历输出到文件(屏幕文件、打印机文件、或磁盘文件)上。思路:该程序主要包括三部分代码:(1)从键盘输入年份和月份。(2)求出该月共多少天和第一天是星期几。(3)按一定格式输出月历。设计程序结构:显然,可以这样组织你的程序:编一个函数,如 PrintYL(Year,Month),它从文件当前位置开始,输出月历,即上述第(3)部分.这个函数许首先要求出该月共多少天和第一天是星期几。显然,可将这部分工作用另外的一或两个函数来实现。于是,你要编写上述第(2)部分的函数。从键盘输入年份和月份,即(1)部分,可以放到

43、 main()函数中,然后调用PrintYL(Year,Month)即可。至于是否还需要其他函数,你在设计(2)(3)部分时再细化。原则是,凡是独立出来比较好的一段代码,一般应当作为一个函数来编写,从而使每一个函数的代码都不会太长,而且功能一目了然。如何求出某月共有多少天和第一天是星期几?这需要使用 和 中的库函数,否则你须自己处理闰年的问题,即每一年的二月份是28 天还是 29 天。如果会确定它们,知道今天是星期几,就可推算出任何一天是星期几了。如果时间来不及,你可拷贝老师编写的下述函数。剩下的工作主要是编写PrintYL(int Year,int Month)函数输出月历和main()函数

44、了。#include /*time functions*/#include /*time functions*/typedef long zmdatetime;/*Unix日期时间格式表示的日期时间*/zmdatetime zmdate(int y,int m,int d)/*给定年月日,返回它的Unix 日期时间格式 */struct date d1;struct time t1;d1.da_year=y;d1.da_mon=m;d1.da_day=d;t1.ti_hour=0;t1.ti_min=0;t1.ti_sec=0;t1.ti_hund=0;return dostounix(&d1

45、,&t1);int zmdayofweek(zmdatetime dt)/*给定日期,返回这一天是星期几:0-6(Sun.-Sat.)*/struct tm*tmp;tmp=localtime(&dt);return tmp-tm_wday;int zmdaysofmonth(int year,int month)/*给定年月,返回该月多少天*/int yday1,days;struct tm*tmp;zmdatetime date1;if(monthtm_yday;date1=zmdate(year,month+1,1);tmp=localtime(&date1);days=(tmp-tm_

46、yday)-yday1;else days=31;return days;如果需要 字符串和整数之间的转换,可以使用下述库函数:#include char *itoa(int value,char*dest,int radix);如“123”123 Int整数 value 转换成 radix进制(2,8,10,16)表示的字符串,放到dest 中,并返回dest。int atoi(const char*s);如 123 “123”将字符串 s 转换成 Int整数(本函数的返回值)。课程实习 2:文件排序给定磁盘 ASCII 文件 Students.txt,它包含若干(不超过 60 个)学生的有

47、关信息,格式如下:姓名 10 系别 9 性 身高出生 8 入学 8 012345678901234567890123456789012345678901234 -Zhang Hai Math Dept F 1.86 19730826 19970915 Wang Jun Math Dept F 1.81 19650921 19960131 Zhou Ling Math Dept M 1.61 19740301 19970915 文件内容,不超过 60 行 Wang Jing Math Dept F 1.75 19720521 19960214 。-注意,数据之间用一个空格符分界。6 个数据项分别

48、占10,9,1,4,8,8 个字符,加上5 个分界符,每行共 45 个正文字符。另,每行尾有2 个字符(r 和 n ),上面看不到。还要注意,姓名和系名本身可能包含空格。题目要求:编一程序,(a)将学生按身高排序后输出到另一新文件(如名为 StHeight.txt)中。(b)计算男生和女生的平均身高,输出到屏幕上。至少要完成(a),有时间再做(b)。(请再思考:如果让程序能按任何数据项排序,又如何实现?)思路:该程序主要包括三部分代码:(1)读 Students.txt文件内容到内存。你须决定用何数据结构来接收数据,例如可用一个二维char 数组,或用一个结构体(struct)s 数组。(2)

49、对数组按身高排序。(3)用数组中的数据计算男生和女生的平均身高,并显示到屏幕上。(4)输出排序后的数组到新文件上。设计程序结构:显然,可以这样组织你的程序:在外层定义数组,如字符数组char ss6050。(ss 在函数中可直接使用,不必作为参数传递。)函数 A:读 Students.txt文件内容到 ss 数组。函数 B:写 ss 数组到 StHeight.txt新文件上。函数 C:ss 数组按身高排序。函数 D:用 ss 数组中的数据计算男生和女生的平均身高,并显示到屏幕上main():调用函数 A,C,B,D。排序可使用任何算法,如冒泡法或插入法。你可参考老师写过的例子(见“指针变量”讲义)。注意,两个字符串比较要使用下面的库函数(#include):int strcmp(const char*s1,const char*s2);/*比较 s1 与 s2,返回整数 0(如果 s1=s2)、负数(s1s2)。*/计算平均身高需要把字符串数据转换为浮点数,你可使用下面的库函数(#include):double atof(const char*s);/*本函数把数字字符串s 转换为 double 浮点数,如atof(“1.81”)是数 1.81。*/

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 实施方案

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com