- 一、文件指针
- 1、fopen打开文件,得到这个文件的文件指针
- 2、fclose关闭文件
- 3、每次一个字符的读写fgetc,fputc,feof,ferror
- 注意:
- 4、每次一行的读写 fgets,fputs
- 注意:
- 安全gets:
- 5、每次读写若干数据块 fread,fwrite
- 注意:
- 6、获取或设置文件当前位置偏移量fseek,ftell,rewind
- 注意:
- 7、标准格式化IO,fprintf,sprintf,fscanf,scanf
- 注意:
FILE指针:每个被使用的文件都在内存中开辟出一个区域,用来存放文件的相关信息,这些信息是保存在一个结构体类型的变量中,该结构体类型是由系统定义的,取名FILE
标准IO预定义的3个流
这三个文件是程序在运行的时候自动打开和关闭的,不需要用户处理
标准IO函数
1、fopen打开文件,得到这个文件的文件指针// 功能 // 获取指定文件的文件指针 // 头文件 #include2、fclose关闭文件 3、每次一个字符的读写fgetc,fputc,feof,ferror// 原型 FILE*fopen(const char *path, const char*mode); // 参数 // path:即将要打开的文件 // mode: // "r:以只读方式打开文件,要求文件必须存在。 // "r+":以读写方式打开文件,要求文件必须存在。 // "w":以只写方式打开文件,文件如果不存在将会创建新文件,如果存在将会将其内容清空。 // "w+”︰以读写方式打开文件,文件如果不存在将会创建新文件,如果存在将会将其内容清空。 // "a":以只写方式打开文件,文件如果不存在将会创建新文件,且文件位置偏移量被自动定位到文件末尾(即以追加方式写数据)。 // "a+":以读写方式打开文件,文件如果不存在将会创建新文件,且文件位置偏移量被自动定位到文件末尾(即以追加方式写数据)。 // 返回值 成功 文件指针 ;失败 NULL
// 功能 讲一个字符写入一个指定的文件 // 头文件 #include// 原型 int fputc(int c, FILE*stream); int putc(int c, FILE *stream); int putchar(int c); // 参数 // c:要写入的字符 // stream:写入的文件指针 // 返回值 成功 写入到的字符 ;失败EOF
// 功能 // ferror():判断一个文件是否遇到了某种错误 // feof():判断一个文件是否到达文件末尾 // 头文件 #include注意:// 原型 int feof(FILE *stream); int ferror(FILE*stream); // 参数 // stream:进行判断的文件指针 // 返回值 // feof如果文件已达末尾则返回真,否则返回假 // ferror如果文件遇到错误则返回真,否则返回假
1,fgec( )、getc()和 getchar()返回值是int,而不是char,原因是因为他们在出错或者读到文件末尾的时候需要返回一个值为-1的EOF标记,而char型数据有可能因为系统的差异而无法表示负整数。
2,当fgec( ). getc()和 getchar()返回EOF时,有可能是发生了错误,也有可能是读到了文件末尾,这是要用feof,ferror判断
3,getchar()缺省从标准输入设备读取一个字符。
4,putchar()缺省从标准输出设备输出一个字符。
5,fgetc()和 fputc( )是函数,getc()和 putc( )是宏定义。
6,两组输入输出函数一般成对地使用,fgetc()和 fputc( ), getc()和 putc( ), getchar()和 putchar().
4、每次一行的读写 fgets,fputs// 功能 // 从指定文件读取最多一行数据头文件 #include注意:// 原型 char*fgets(char *s, int size,FILE*stream); char *gets(char *s); // s:自定义缓冲区指针参数 // size:自定义缓冲区大小 // stream:即将被读取数据的文件指针 // 返回值: 成功自定义缓冲区指针s;失败NULL // 备注: // 1,gets()缺省从文件 stdin读入数据 // 2,当返回NULL时,文件 stream可能已达末尾,或者遇到错误
1,fgets()跟fgetc()一样,当其返回NULL时并不能确定究竟是达到文件末尾还是碰到错误,需要用feof( )/ferror( )来进一步判断。
2,fgets()每次读取至多不超过size个字节的一行,所谓“一行”即数据至多包含一个换行符n’。
3,gets()是一个已经过时的接口,因为他没有指定自定义缓冲区s的大小,这样很容易造成缓冲区溢出,导致程序段访问错误。
4,fgets()和 fputs( ), gets()和 puts( )一般成对使用,鉴于gets( )的不安全性,一般建议使用前者。
安全gets:char *sgets(char *str,int len){//安全gets
fgets(str,len,stdin);
if(str[strlen(str)-1]=='n'){
str[strlen(str)-1]=' ';
}
return str;
}
5、每次读写若干数据块 fread,fwrite
// 功能 // 从指定文件读取若干个数据块 // 头文件 #include// 原型 size_t fread(void *ptr,size_t size, size_t nmemb,FILE *stream); // 参数 // ptr:自定义缓冲区指针 // size:数据块大小 // nmemb:数据块个数 // stream:即将被读取数据的文件指针 // 返回值 成功 读取的数据块个数,等于nmemb ;失败 读取的数据块个数,小于nmemb或等于0 // 备注 // 当返回小与nmemb时,文件 stream可能已达末尾,或者遇到错误
// 功能 // 将若干块数据写入指定的文件 // 头文件 // #include注意:// 原型 // size_t fwrite(const void *ptr,size_t size,size_t nmemb,FILE*stream);ptr:自定义缓冲区指针 // 参数 // size:数据块大小 // nmemb:数据块个数 // stream:即将被写入数据的文件指针 // 返回值 // 成功 写入的数据块个数,等于sinmembze; 失败 写入的数据块个数,小于nmemb或等于0
如果fread()返回值小于nmemb 时,则可能已达末尾,或者遇到错误,需要借助于feof( )/ferror()来加以进一步判断。
6、获取或设置文件当前位置偏移量fseek,ftell,rewind// 功能 // 设置指定文件的当前位置偏移量 // 头文件 #include// 原型 int fseek(FILE*stream, long offset,int whence); // 参数 // stream:需要设置位置偏移量的文件指针 // offset:新位置偏移量相对基准点的偏移 // whence:基准点 // SEEK_SET:文件开头处 // SEEK_CUR:当前位置 // SEEK_END:文件末尾处 // 返回值 成功o 失败-1
// 功能 // 获取指定文件的当前位置偏移量 // 头文件 #include// 原型 long ftell(FILE*stream); // 参数 // stream:需要返回当前文件位置偏移量的文件指针 // 返回值 成功 当前文件位置偏移量 ;失败 -1
// 功能 // 将指定文件的当前位置偏移量设置到文件开头处 // 头文件 #include注意:// 原型 void rewind(FILE*stream); // 参数 // stream:需要设置位置偏移量的文件指针 // 备注 // 该函数的功能是将文件strean的位置偏移量置位到文件开头处。
1,fseek()的用法基本上跟系统IO的 lseek( )是一致的。
2,rewind(fp)相等于fseek(fp, OL,SEEK_SE);
7、标准格式化IO,fprintf,sprintf,fscanf,scanf// 功能 // 将格式化数据写入指定的文件或者内存 // 头文件 #include// 原型 int fprintf(FILE *restrict stream, const char *restrict format,...);int printf(const char *restrict format,...); int snprintf(char *restrict s, size_t n,const char *restrict format,...);int sprintf(char *restrict s, const char *restrict format,...); // 参数 // stream:写入数据的文件指针 // format:格式控制串 // s:写入数据的自定义缓冲区n:自定义缓冲区的大小 // 返回值 // 成功 成功写入的字节数 ;失败 -1
// 功能 // 从指定的文件或者内存中读取格式化数据 // 头文件 #include注意:// 原型 int fscanf(FILE*restrict stream, const char *restrict format,... ); int scanf(const char *restrict format,... ); int sscanf(const char *restrict s, const char *restrict format,... ); // 参数 // stream:读出数据的文件指针 // format:格式控制串 // s:读出数据的自定义缓冲区 // 返回值 // 成功 正确匹配且赋值的数据个数 ;失败 EOF
1,fprintf( )不仅可以像printf()一样向标准输出设备输出信息,也可以向由stream指定的任何有相应权限的文件写入数据。
2,sprintf()和 snprintf()都是向一块自定义缓冲区写入数据,不同的是后者第二个参数提供了这块缓冲区的大小,避免缓冲区溢出,因此应尽量使用后者,放弃使用前者。
3,fscanf()不仅可以像scanf()一样从标准输入设备读入信息,也可以从由stream指定的任何有相应权限的文件读入数据。
4,sscanf()从一块由s指定的自定义缓冲区中读入数据。
// 格式控制符 // %d 有符号十进制整型数 // %u 无符号十进制整型数 // %o 无符号八进制整型数 // %x 无符号十六进制整型数 // %c 字符 // %s 字符串 // %f 计数法单精度浮点数 // %e 科学技术法单精度浮点数 // %p 指针 // %.5s 取字符串的前5个字符 // %.5f 取单精度浮点数小数点后5位小数 // %5d 位宽至少为5个字符,右对齐 // %-5d 位宽至少为5个字符,左对齐 // %hd 半个有符号数十进制整型数 // %hhd 半半个有符号数十进制整型数 // %lf /%le 双精度浮点数 // %Lf / %Le 长双精度浮点数
cp fsrc fdst
#include#include #include int main(int argc, char const *argv[]) { long pos1,pos2,total=0; if(argc!=3){ printf("Usage: %s n",argv[0]); } FILE *fp_src = fopen(argv[1],"r"); FILE *fp_dst = fopen(argv[2],"w"); if(fp_dst==NULL||fp_src==NULL){ perror("fopen"); return -1; } char *buf = malloc(100); while(1) { bzero(buf,100); pos1=ftell(fp_src); int ret = fread(buf,100,1,fp_src); pos2=ftell(fp_src); if(ret==1) { fwrite(buf,100,1,fp_dst); } else { fwrite(buf,pos2-pos1,1,fp_dst); } if(feof(fp_src)) break; } free(buf); return 0; }



