fopen()函数
1.2  ⽂件的输⼊输出函数
键盘、显⽰器、打印机、磁盘驱动器等逻辑设备, 其输⼊输出都能够通过⽂件管理的⽅法来完毕。⽽在编程时使⽤最多的要算是磁盘⽂件, 因此本节主要以磁盘⽂件为主, 具体介绍Turbo C2.0提供的⽂件操作函数, 当然这些对⽂件的操作函数也适合于⾮磁盘⽂件的情况。
另外, Turbo C2.0提供了两类关于⽂件的函数。⼀类称做标准⽂件函数也称缓冲型⽂件函数, 这是ANSI标准定义的函数; 还有⼀类叫⾮标准⽂件函数, 也称⾮缓冲型⽂件函数。这类函数最早公⽤于UNIX操作系统, 但如今MS-DOS3.0以上版本号的操作系统也能够使⽤。以下分别进⾏介绍。
1.2.1标准⽂件函数
标准⽂件函数主要包含⽂件的打开、关闭、读和写等函数。不象BASIC 、 FORTRAN语⽅有顺序⽂件和随机⽂件之分,  在打开时就应按不同的⽅式确定。 Turbo C2.0并不区分这两种⽂件, 但提供了两组函数, 即顺序读写函数和随机读写函数。
⼀、⽂件的打开和关闭
不论什么⼀个⽂件在使⽤之前和使⽤之后, 必需要进⾏打开和关闭, 这是由于操作系统对于同⼀时候打开的⽂件数⽬是有限制的, DOS操作系统中,    能够在DEVICE .SYS 中定义同意同⼀时候打开的⽂件数n(⽤files=n定义)。当中n 为可同⼀时候打开的⽂件数, ⼀般n<=20。因此在使⽤⽂件前应打开⽂件, 才可对当中的信息进⾏存取。⽤完之后需要关闭, 否则将会出现⼀些意想不到的错误。Turbo C2.0提供了打开和关闭⽂件的函数。
1. fopen()函数
fopen函数⽤于打开⽂件, 其调⽤格式为:
FILE *fopen(char *filename, *type);
fgets和fgetc的区别在介绍这个函数之;前, 先了解⼀下以下的知识。
(1) 流(stream)和⽂件(file)
流和⽂件在Turbo C2.0中是有差别的, Turbo C2.0为编程者和被訪问的设备之间提供了⼀层抽象的东西, 称之为"流", ⽽将详细的实际设备叫做⽂件。流是⼀个逻辑设备, 具有相同的⾏为。因此, ⽤来进⾏磁盘⽂件写的函数也相同能够⽤来进⾏打印机的写⼊。在Turbo C2.0中有两种性质的流:  ⽂字流( text stream)和⼆进制(binary stream)。对磁盘来说就是⽂本⽂件和⼆进制⽂件。本软件为了便于让读者易
理解Turbo C2.0语⾔⽽没有对流和⽂件作特别区分。
(2) ⽂件指针FILE
实际上FILE是⼀个新的数据类型。它是Turbo C2.0的基本数据类型的集合, 称之为结构指针。有关结构的概念将在第四节中具体介绍, 这⾥仅仅要将FILE理解为⼀个包含了⽂件管理有关信息的数据结构, 即在打开⽂件时必须先定义⼀个⽂件指针。
(3) 以后介绍的函数调⽤格式将直接写出形式參数的数据类型和函数返回值的数据类型。⽐如: 上⾯打开⽂件的函数, 返回⼀个⽂件指针, 当中形式參数有两个, 均为字符型变量(字符串数组或字符串指针)。本软件不再对函数的调⽤格式作具体说明。
如今再来看打开⽂件函数的使⽤⽅法。
fopen()函数中第⼀个形式參数表⽰⽂件名称, 能够包括路径和⽂件名称两部分。如:
"B:TEST.DAT"
"C://TC//TEST.DAT"
假设将路径写成"C:/T C/T EST.DAT"是不对的, 这⼀点要特别注意。
第⼆个形式參数表⽰打开⽂件的类型。关于⽂件类型的规定參见下表。
表⽂件操作类型
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
字符含义
────────────────────────────
"r"打开⽂字⽂件仅仅读
"w"创建⽂字⽂件仅仅写
"a"增补, 假设⽂件不存在则创建⼀个
"r+"打开⼀个⽂字⽂件读/写
"w+"创建⼀个⽂字⽂件读/写
"a+"打开或创建⼀个⽂件增补
"b"⼆进制⽂件(能够和上⾯每⼀项合⽤)
"t"⽂这⽂件(默认项)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
假设要打开⼀个CCDOS⼦⽂件夹中, ⽂件名称为CLIB的⼆进制⽂件, 可写成:
fopen("c://ccdos//clib", "rb");
假设成功的打开⼀个⽂件, fopen()函数返回⽂件指针,  否则返回空指针 (NULL)。由此可推断⽂件打开是否成功。
2. fclose()函数
fclose()函数⽤来关闭⼀个由fopen()函数打开的⽂件 , 其调⽤格式为:
int fclose(FILE *stream);
该函数返回⼀个整型数。当⽂件关闭成功时, 返回0, 否则返回⼀个⾮零值。能够依据函数的返回值推断⽂件是否关闭成功。
例10:
#iclude<stdio.h>
main()
{
FILE *fp;                /*定义⼀个⽂件指针*/
int i;
fp=fopen("CLIB", "rb");  /*打开当前⽂件夹名为CLIB的⽂件仅仅读*/
if(fp==NULL)            /*推断⽂件是否打开成功*/
puts("File open error");/*提⽰打开不成功*/
i=fclose(fp);            /*关闭打开的⽂件*/
if(i==0)                /*推断⽂件是否关闭成功*/
printf("O,K");        /*提⽰关闭成功*/
else
puts("File close error");/*提⽰关闭不成功*/
}
⼆、有关⽂件操作的函数
本节所讲的⽂件读写函数均是指顺序读写, 即读写了⼀条信息后, 指针⾃⼰主动加1。以下分别介绍写操作函数和读操作函数。
1.⽂件的顺序写函数
fprintf()、fputs()和fputc()函数
函数fprintf()、fputs()和fputc()均为⽂件的顺序写操作函数,  其调⽤格式例如以下:
int fprintf(FILE *stream, char *format, <variable-list>);
int fputs(char *string, FILE *steam);
int fputc(int ch, FILE *steam);
上述三个函数的返回值均为整型量。fprintf() 函数的返回值为实际写⼊⽂件⾥的字罕个数(字节数)。假设写错误, 则返回⼀个负数, fputs()函数返回0时表明将string指针所指的字符串写⼊⽂件⾥的操作成功, 返回⾮0时,  表明写操作失败。fputc()函数返回⼀个向⽂件所写字符的值, 此时写操作成功,  否则返回EOF(⽂件结束结束其值为-1, 在stdio.h 中定义)表⽰写操作错误。
fprintf( ) 函数中格式化的规定与printf( ) 函数同样,  所不同的仅仅是 fprintf()函数是向⽂件⾥写⼊。⽽printf()是向屏幕输出。
以下介绍⼀个样例, 执⾏后产后⼀个test.dat的⽂件。
例11:
#include<stdio.h>
main()
{
char *s="That's good news";  /*定义字符串指针并初始化*/
int i=617;                    /*定义整型变量并初始化*/
FILE *fp;                    /*定义⽂件指针*/
fp=fopne("test.dat", "w");    /*建⽴⼀个⽂字⽂件仅仅写*/
fputs("Your score of TOEFLis", fp);/*向所建⽂件写⼊⼀串字符*/
fputc(':', fp);              /*向所建⽂件写冒号:*/
fprintf(fp, "%d/n", i);      /*向所建⽂件写⼀整型数*/
fprintf(fp, "%s", s);        /*向所建⽂件写⼀字符串*/
fclose(fp);                  /*关闭⽂件*/
}
⽤DOS的TYPE命令显⽰TEST.DAT的内容例如以下所看到的:
屏幕显⽰
Your score of TOEFL is: 617
That's good news
2.⽂件的顺序读操作函数
fscanf()、fgets()和fgetc()函数
函数fscanf()、fgets()和fgetc()均为⽂件的顺序读操作函数, 其调⽤格式例如以下:
int fscanf(FILE *stream, char *format, <address-list>);
char fgets(char *string, int n, FILE *steam);
int fgetc(FILE *steam);
fscanf()函数的使⽤⽅法与scanf()函数类似,  仅仅是它是从⽂件⾥读到信息。 fscanf()函数的返回值为EOF(即-1), 表明读错误, 否则读数据成功。fgets()函数从⽂件⾥读取⾄多n-1个字符(n⽤来指定字符数), 并把它们放⼊string指向的字符串中, 在读⼊之后⾃⼰主动向字符串未尾加⼀个空字符, 读成功返回string指针, 失败返回⼀个空指针。fgetc ()函数返回⽂件当前位置的⼀个字符,  读错误时返回EOF。
以下程序读取例11产⽣的test.dat⽂件, 并将读出的结果显⽰在屏幕上。
例12
#include<stdio.h>
main()
{
char *s, m[20];
int i;
FILE  *fp;
fp=fopen("test.dat", "r");    /*打开⽂字⽂件仅仅读*/
fgets(s, 24, fp);            /*从⽂件⾥读取23个字符*/
printf("%s", s);              /*输出所读的字符串*/
fscanf(fp, "%d", &i);        /*读取整型数*/
printf("%d", i);              /*输出所读整型数*/
putchar(fgetc(fp));          /*读取⼀个字符同⼀时候输出*/
fgets(m, 17, fp);            /*读取16个字符*/
puts(m);                      /*输出所读字符串*/
fclose(fp);                  /*关闭⽂件*/
getch();                      /*等待任⼀键*/
}
执⾏后屏幕显⽰:
Your score of TOEFL is: 617
That's good news
假设将上例中fscanf(fp, "%d", &i)改为fscanf(fp, "%s", m),  再将其后的输出语句改为printf("%s", m), 则可得出相同的结果。由此可见Turbo C2. 0中仅仅要是读⽂字⽂件,则不论是字符还是数字都将按其ASCII值处理。另外还要说明的⼀点就是fscanf()函数读到空⽩符时, 便⾃⼰主动结束, 在使⽤时要特别注意。
3.⽂件的随机读写
有时⽤户想直接读取⽂件⾥间某处的信息, 若⽤⽂件的顺序读写必须从⽂件头開始直到要求的⽂件位置再读, 这显然不⽅便。Turbo C2.0提供了⼀组⽂件的随机读写函数, 即能够将⽂件位置指针定位在所要求读写的地⽅直接读写。
⽂件的随机读写函数例如以下:
int fseek (FILE *stream, long offset, int fromwhere);
int fread(void *buf, int size, int count, FILE *stream);
int fwrite(void *buf, int size, int count, FILE *stream);
long ftell(FILE *stream);
fseek()函数的作⽤是将⽂件的位置指针设置到从fromwhere開始的第offset 字节的位置上, 当中fromwhere是下列⼏个宏定义之中的⼀个:
⽂件位置指针起始计算位置fromwhere ━━━━━━━━━━━━━━━━━━━━━━━━━━━
符号常数数值含义───────────────────────────
SEEK_SET0从⽂件开头
SEEK_CUR1从⽂件指针的现⾏位置
SEEK_END2从⽂件末尾━━━━━━━━━━━━━━━━━━━━━━━━━━━
offset是指⽂件位置指针从指定開始位置(fromwhere指出的位置)跳过的字节数。它是⼀个长整型量, 以⽀持⼤于64K字节的⽂件。fseek()函数⼀般⽤于对⼆进制⽂件进⾏操作。
当fseek()函数返回0时表明操作成功, 返回⾮0表⽰失败。
以下程序从⼆进制⽂件test_b.dat中读取第8个字节。
例13:
#include<stdio.h>
main()
{
FILE *fp;
if((fp=fopen("test_b.dat", "rb"))==NULL)
{
printf("Can't open file");
exit(1);
}
fseek(fp, 8.1, SEEK_SET);
fclose(fp);
}
fread()函数是从⽂件⾥读count个字段, 每⼀个字段长度为size个字节, 并把它们存放到buf指针所指的缓冲器中。
fwrite()函数是把buf指针所指的缓冲器中, 长度为size个字节的count个字段写到stream指向的⽂件⾥去。
随着读和写字节数的增⼤, ⽂件位置指⽰器也增⼤, 读多少个字节, ⽂件位置指⽰器对应也跳过多少个字节。读写完成函数返回所读和所写的字段个数。
ftell()函数返回⽂件位置指⽰器的当前值,  这个值是指⽰器从⽂件头開始算起的字节数, 返回的数为长整型数, 当返回-1时, 表明出现错误。
以下程序把⼀个浮点数组以⼆进制⽅式写⼊⽂件test_b.dat中。
例14:
#include <stdio.h>
main()
{
float f[6]={3.2, -4.34, 25.04, 0.1, 50.56, 80.5};
/*定义浮点数组并初始化*/
int i;
FILE *fp;
fp=fopen("test_b.dat", "wb"); /*创建⼀个⼆进制⽂件仅仅写*/
fwrite(f, sizeof(float), 6, fp);/*将6个浮点数写⼊⽂件⾥*/
fclose(fp);                  /*关闭⽂件*/
}
以下样例从test_b.dat⽂件⾥读100个整型数, 并把它们放到dat数组中。
例15:
#include <stdio.h>
main()
{
FILE *fp;
int dat[100];
fp=fopen("test_b.dat", "rb");/*打开⼀个⼆进制⽂件仅仅读*/
if(fread(dat, sizeof(int), 100, fp)!=100)
/*推断是否读了100个数*/
{
if(feof(fp))
printf("End of file"); /*不到100个数⽂件结束*/
else
printf("Read error");  /*读数错误*/
fclose(fp);                  /*关闭⽂件*/
}
注意:
当⽤标准⽂件函数对⽂件进⾏读写操作时, ⾸先将所读写的内容放进缓冲区, 即写函数仅仅对输出缓冲区进⾏操作, 读函数仅仅对输⼊缓冲区进⾏操作。⽐如向⼀个⽂件写⼊内容, 所写的内容将⾸先放在输出缓冲区中, 直到输出缓冲区存满或使⽤fclose()函数关闭⽂件时, 缓冲区的内容才会写⼊⽂件⾥。若⽆fclose() 函数, 则不会向⽂件⾥存⼊所写的内容或写⼊的⽂件内容不全。有⼀个对缓冲区进⾏刷新的函数, 即fflush(), 其调⽤格式为:
int fflush(FILE *stream);
该函数将输出缓冲区的内容实际写⼊⽂件⾥, ⽽将输⼊缓冲区的内容清除掉。
4. feof()和rewind()函数
这两个函数的调⽤格式为:
int feof(FILE *stream);
int rewind(FILE *stream);
feof()函数检測⽂件位置指⽰器是否到达了⽂件结尾,  若是则返回⼀个⾮0值, 否则返回0。这个函数对⼆进制⽂件操作特别实⽤, 由于⼆进制⽂件⾥,  ⽂件结尾标志EOF也是⼀个合法的⼆进制数,  仅仅简单的检查读⼊字符的值来推断⽂件是否结束是不⾏的。假设那样的话, 可能会造成⽂件未结尾⽽被觉得结尾, 所以就必须有feof()函数。
以下的这条语句是经常使⽤的推断⽂件是否结束的⽅法。
while(!feof(fp))
fgetc(fp);
while为循环语句, 将在以下介绍。
rewind()函数⽤于把⽂件位置指⽰器移到⽂件的起点处, 成功时返回0,  否则, 返回⾮0值。
1.2.2⾮标准⽂件函数
这类函数最早⽤于UNIX操作系统, ANSI标准没有定义,  但有时也经经常使⽤到, DOS 3.0以上版本号⽀持这些函数。它们的头⽂件为io.h。
⼀、⽂件的打开和关闭
1. open()函数
open()函数的作⽤是打开⽂件, 其调⽤格式为:
int open(char *filename, int access);
该函数表⽰按access的要求打开名为filename的⽂件, 返回值为⽂件描写叙述字, 当中access有两部分内容: 基本模式和修饰符, 两者⽤" "("或")⽅式连接。修饰符能够有多个, 但基本模式仅仅能有⼀个。access的规定如表3-2。
表3-2  access的规定━━━━━━━━━━━━━━━━━━━━━━━━━━━━基本模式含义修饰符含义──────────────────────────── O_RDONLY    仅仅读  O_APPEND  ⽂件指针指向末尾 O_WRONLY    仅仅写  O_CREAT    ⽂件不存在时创建⽂件,
属性按基本模式属性 O_RDWR      读写  O_TRUNC    若⽂件存在, 将其长度
缩为0, 属性不变
O_BINARY  打开⼀个⼆进制⽂件
O_TEXT    打开⼀个⽂字⽂件━━━━━━━━━━━━━━━━━━━━━━━━━━━━
open()函数打开成功, 返回值就是⽂件描写叙述字的值(⾮负值), 否则返回-1。
2. close()函数
close()函数的作⽤是关闭由open()函数打开的⽂件, 其调⽤格式为:
int close(int handle);
该函数关闭⽂件描写叙述字handle相连的⽂件。
⼆、读写函数
1. read()函数
read()函数的调⽤格式为:
int read(int handle, void *buf, int count);
read()函数从handle(⽂件描写叙述字)相连的⽂件⾥, 读取count个字节放到buf 所指的缓冲区中, 返回值为实际所读字节数, 返回-1表⽰出错。返回0表⽰⽂件结束。
write()函数的调⽤格式为:
int write(int handle, void *buf, int count);
write()函数把count个字节从buf指向的缓冲区写⼊与handle相连的⽂件⾥, 返回值为实际写⼊的字节数。
三、随机定位函数
1. lseek()函数
lseek()函数的调⽤格式为:
int lseek(int handle, long offset, int fromwhere);
该函数对与handle相连的⽂件位置指针进⾏定位, 功能和使⽤⽅法与fseek() 函数同样。
2. tell()函数
tell()函数的调⽤格式为:
long tell(int handle);
该函数返回与handle相连的⽂件现⽣位置指针, 功能和使⽤⽅法与ftell()同样。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。