一、fopen
fopen函数用于打开文件, 其调用格式为:FILE *fopen(char *filename, *type);
fopen()函数中第一个形式参数表示文件名, 可以包含路径和文件名两部分。
格式:“B:TEST.DAT"或者"C:\TC\TEST.DAT"
fopen函数用来打开一个文件,其调用的一般形式为: 文件指针名=fopen(文件名,使用文件方式)
其中,“文件指针名”必须是被说明为FILE 类型的指针变量,“文件名”是被打开文件的文件名。
“使用文件方式”是指文件的类型和操作要求。“文件名”是字符串常量或字符串数组。例如:
FILE *fp;
fp = ("file a","r");
其意义是在当前目录下打开文件file a, 只允许进行“读”操作,并使fp指向该文件。
又如:
FILE *fphzk
fphzk=("c:\hzk16","rb")
其意义是打开C驱动器磁盘的根目录下的文件hzk16, 这是一个二进制文件,只允许按二进制方式进行读操作。
两个反斜线“ ”中的第一个表示转义字符,第二个表示根目录。使用文件的方式共有12种,下面给出了它们的符号和意义。
第二个形式参数表示打开文件的类型。关于文件类型的规定参见下表。
字符 | 含义 |
---|---|
r | 打开文件只读 |
w | 打开文件只写 |
a | 增补,如果文件不存在创建一个 |
r+ | 打开一个文字文件读/写 |
w+ | 创建一个文字文件读/写 |
a+ | 打开或创建一个文件增补 |
b | 二进制文件(可以和上面每一项合用) |
rb | 只读打开一个二进制文件,只允许读数据 |
wb | 只写打开或建立一个二进制文件,只允许写数据 |
ab | 追加打开一个二进制文件,并在文件末尾写数据 |
rt+ | 读写打开一个文本文件,允许读和写 |
wt+ | 读写打开或建立一个文本文件,允许读写 |
at+ | 读写打开一个文本文件,允许读,或在文件末追加数据 |
rb+ | 读写打开一个二进制文件,允许读和写 |
wb+ | 读写打开或建立一个二进制文件,允许读和写 |
ab+ | 读写打开一个二进制文件,允许读,或在文件末追加数据 |
对于文件使用方式有以下几点说明:
- 文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:
r(read): 读
w(write): 写
a(append): 追加
t(text): 文本文件,可省略不写
b(banary): 二进制文件
+: 读和写 - 凡用“r”打开一个文件时,该文件必须已经存在, 且只能从该文件读出。
- 用“w”打开的文件只能向该文件写入。 若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。
- 若要向一个已存在的文件追加新的信息,只能用“a”方式打开文件。
- 在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。因此常用以下程序段打开文件:
if((fp=fopen("c:\hzk16","rb")==NULL)
{
printf("
error on open c:\hzk16 file!");
getch();
exit(1);
}
这段程序的意义是,如果返回的指针为空,表示不能打开C盘根目录下的hzk16文件,则给出提示信息 “error on open c: hzk16file!”,下一行getch()的功能是从键盘输入一个字符,但不在屏幕上显示。在这里,该行的作 用是等待, 只有当用户从键盘敲任一键时,程序才继续执行, 因此用户可利用这个等待时间阅读出错提示。敲键后执行exit(1)退出程序。
- 把一个文本文件读入内存时,要将ASCII码转换成二进制码, 而把文件以文本方式写入磁盘时,也要把二进制码转换成ASCII码,因此文本文件的读写要花费较多的转换时间。对二进制文件的读写不存在这种转换。
- 标准输入文件(键盘),标准输出文件(显示器 ),标准出错输出(出错信息)是由系统打开的,可直接使用。文件关闭函数fclose文件一旦使用完毕,应用关闭文件函数把文件关闭, 以避免文件的数据丢失等错误。
二、fclose
fclose()函数用来关闭一个由fopen()函数打开的文件 。
其调用格式为: int fclose(FILE *stream); 该函数返回一个整型数。当文件关闭成功时, 返回0, 否则返回一个非零值。可以根据函数的返回值判断文件是否关闭成功。
FILE *fpOut=fopen("c:\a.txt","wt+");
int a=1;
fprintf(fpOut,"%d",a);
fclose(fpOut);
当前指针不是null 是0 注意
三、fread与fwrite
- 作用
读写文件数据块。
- 函数原型
(1)size_t fread ( void * ptr, size_t size, size_t nmemb, FILE * stream );
其中,ptr:指向保存结果的指针;size:每个数据类型的大小;count:数据的个数;stream:文件指针函数返回读取数据的个数。
(2)size_t fwrite ( const void * ptr, size_t size, size_t nmemb, FILE * stream );
其中,ptr:指向保存数据的指针;size:每个数据类型的大小;count:数据的个数;stream:文件指针
函数返回写入数据的个数。
- 注意
(1)写操作fwrite()后必须关闭流fclose()。
(2)不关闭流的情况下,每次读或写数据后,文件指针都会指向下一个待写或者读数据位置的指针。
返回值:读或写的记录数,成功时返回的记录数等于nmemb,出错或读到文件末尾时返回的记录
数小于nmemb,也可能返回0。
fread和fwrite用于读写记录,这里的记录是指一串固定长度的字节,比如一个int、一个结构体或者一个定长数组。参数size指出一条记录的长度,而nmemb指出要读或写多少条记录,这些记录在ptr所指的内存空间中连续存放,共占size * nmemb个字节,fread从文件stream中读出size * nmemb个字节保存到ptr中,而fwrite把ptr中的size * nmemb个字节写到文件stream中。
nmemb是请求读或写的记录数,fread和fwrite返回的记录数有可能小于nmemb指定的记录数。例如当前读写位置距文件末尾只有一条记录的长度,调用fread时指定nmemb为2,则返回值为1。如果当前读写位置已经在文件末尾了,或者读文件时出错了,则fread返回0。如果写文件时出错了,则fwrite的返回值小于nmemb指定的值。
四、fseek
int fseek(FILE *stream, long int offset, int whence) 设置流 stream 的文件位置为给定的偏移 offset,参数 offset 意味着从给定的 whence 位置查找的字节数。
参数
-
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
-
offset -- 这是相对 whence 的偏移量,以字节为单位。
-
whence -- 这是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一:
常量 描述 SEEK_SET 件的开头 SEEK_CUR 文件指针的当前位置 SEEK_END 文件的末尾 fseek(fp,100L,0);把fp指针移动到离文件开头100字节处;
fseek(fp,100L,1);把fp指针移动到离文件当前位置100字节处;
fseek(fp,-100L,2);把fp指针退回到离文件结尾100字节处。 -
返回值
如果成功,则该函数返回零,否则返回非零值。
#include <stdio.h>
#define N 5
typedef struct student {
long sno;
char name[10];
float score[3];
} STU;
void fun(char *filename, STU n)
{
FILE *fp;
fp = fopen(filename, "rb+");
fseek(fp, -1L*sizeof(STU),SEEK_END);
fwrite(&n, sizeof(STU), 1, fp);
fclose(fp);
}
int main()
{
STU t[N]={ {10001,"MaChao", 91, 92, 77}, {10002,"CaoKai", 75, 60, 88},
{10003,"LiSi", 85, 70, 78}, {10004,"FangFang", 90, 82, 87},
{10005,"ZhangSan", 95, 80, 88}};
STU n={10006,"ZhaoSi", 55, 70, 68}, ss[N];
int i,j; FILE *fp;
fp = fopen("student.dat", "wb");
fwrite(t, sizeof(STU), N, fp);
fclose(fp);
fp = fopen("student.dat", "rb");
fread(ss, sizeof(STU), N, fp);
fclose(fp);
printf("
The original data :
");
for (j=0; j<N; j++)
{
printf("
No: %ld Name: %-8s Scores: ",ss[j].sno, ss[j].name);
for (i=0; i<3; i++)
printf("%6.2f ", ss[j].score[i]);
printf("
");
}
fun("student.dat", n);
printf("
The data after modifing :
");
fp = fopen("student.dat", "rb");
fread(ss, sizeof(STU), N, fp);
fclose(fp);
for (j=0; j<N; j++)
{
printf("
No: %ld Name: %-8s Scores: ",ss[j].sno, ss[j].name);
for (i=0; i<3; i++)
printf("%6.2f ", ss[j].score[i]);
printf("
");
}
}
The original data :
No: 10001 Name: MaChao Scores: 91.00 92.00 77.00
No: 10002 Name: CaoKai Scores: 75.00 60.00 88.00
No: 10003 Name: LiSi Scores: 85.00 70.00 78.00
No: 10004 Name: FangFang Scores: 90.00 82.00 87.00
No: 10005 Name: ZhangSan Scores: 95.00 80.00 88.00
The data after modifing :
No: 10001 Name: MaChao Scores: 91.00 92.00 77.00
No: 10002 Name: CaoKai Scores: 75.00 60.00 88.00
No: 10003 Name: LiSi Scores: 85.00 70.00 78.00
No: 10004 Name: FangFang Scores: 90.00 82.00 87.00
No: 10006 Name: ZhaoSi Scores: 55.00 70.00 68.00
五、fprintf与fscanf
fprintf:传送格式化输出到一个文件中
函数原型:int fprintf(FILE stream, char format[, argument,...]);
FILE 一个FILE型的指针
char 格式化输入函数,和printf里的格式一样
返回值:成功时返回转换的字节数,失败时返回一个负数
#include<stdio.h>
#include<iostream>
int main()
{
FILE* f = fopen("C:\1.txt","a+");
char str[6] = "hello";
fprintf(f,"%s
",str);
fclose(f);
}
fscanf:从一个流中执行格式化输入
函数原型:int fscanf(FILE stream, char format[,argument...]);
FILE 一个FILE型的指针
char 格式化输出函数,和scanf里的格式一样
返回值:成功时返回转换的字节数,失败时返回一个负数
#include<stdio.h>
#include<iostream>
int main()
{
long dev;
long offset;
long length;
char ch;
double ts=0.000000;
FILE* fd = fopen("C://1.txt","r");
if(5 == fscanf(fd,"%ld,%ld,%ld,%c,%lf
",&dev,&offset,&length,&ch,&ts))
{
printf("%ld,%ld,%ld,%c,%lf
",dev,offset,length,ch,ts);
}
fclose(fd);
return 0;
}
六、feof
检查文件流是否读到了文件尾)
int feof(FILE * stream);
函数说明 feof()用来侦测是否读取到了文件尾,尾数stream为fopen()所返回之文件指针。如果已到文件尾则返回非零值,其他情况返回0。
返回值 返回非零值代表已到达文件尾。
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
fp = fopen("file.txt","r");
if(fp == NULL)
{
perror("打开文件时发生错误");
return(-1);
}
while(1)
{
c = fgetc(fp);
if( feof(fp) )
{
break ;
}
printf("%c", c);
}
fclose(fp);
return(0);
}
七、fgetc与fputc
定义函数 int fgetc(FILE * stream);
从指定的流 stream 获取下一个字符(一个无符号字符),并把位置标识符往前移动。若读到文件尾而无数据时便返回EOF。
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
int n = 0;
fp = fopen("file.txt","r");
if(fp == NULL)
{
perror("打开文件时发生错误");
return(-1);
}
do
{
c = fgetc(fp);
if( feof(fp) )
{
break ;
}
printf("%c", c);
}while(1);
fclose(fp);
return(0);
}
int fputc(int c,FILE * stream);
fputc 会将参数c 转为unsigned char 后写入参数stream 指定的文件中。
返回值 fputc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。
#include <stdio.h>
int main ()
{
FILE *fp;
int ch;
fp = fopen("file.txt", "w+");
for( ch = 33 ; ch <= 100; ch++ )
{
fputc(ch, fp);
}
fclose(fp);
return(0);
}
八、fgets与fputs
char * fgets(char * s,int size,FILE * stream);
函数说明 fgets()用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符、读到文件尾或是已读了size-1个字符为止,最后会加上NULL作为字符串结束。
返回值 gets()若成功则返回s指针,返回NULL则表示有错误发生。
#include <stdio.h>
int main()
{
FILE *fp;
char str[60];
/* 打开用于读取的文件 */
fp = fopen("file.txt" , "r");
if(fp == NULL) {
perror("打开文件时发生错误");
return(-1);
}
if( fgets (str, 60, fp)!=NULL ) {
/* 向标准输出 stdout 写入内容 */
puts(str);
}
fclose(fp);
return 0;
}
int fputs(const char * s,FILE * stream);
fputs()用来将参数s所指的字符串写入到参数stream所指的文件内。
返回值 若成功则返回写出的字符个数,返回EOF则表示有错误发生。
#include <stdio.h>
int main ()
{
FILE *fp;
fp = fopen("file.txt", "w+");
fputs("1", fp);
fputs("2", fp);
fclose(fp);
return(0);
}
九、freopen
定义函数 FILE * freopen(const char * path,const char * mode,FILE * stream);
函数说明 参数path字符串包含欲打开的文件路径及文件名,参数mode请参考fopen()说明。参数stream为已打开的文件指针。Freopen()会将原stream所打开的文件流关闭,然后打开参数path的文件。
返回值 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno 中。
#include <stdio.h>
int main(){
FILE * fp;
fp=fopen("C://1.txt","r");
fp=freopen("C://2.txt","r",fp);
fclose(fp);
return 0;
}
十、ftell
long ftell(FILE * stream);
函数说明 ftell()用来取得文件流目前的读写位置。参数stream为已打开的文件指针。
返回值 当调用成功时则返回目前的读写位置,若有错误则返回-1,errno会存放错误代码。
#include <stdio.h>
int main ()
{
FILE *fp;
int len;
fp = fopen("file.txt", "r");
if( fp == NULL )
{
perror ("打开文件错误");
return(-1);
}
fseek(fp, 0, SEEK_END);
len = ftell(fp);
fclose(fp);
printf("file.txt 的总大小 = %d 字节
", len);//19
return(0);
}