FILE指针:每个被使用的文件都在内存中开辟出一个区域,用来存放文件的相关信息,这些信息是保存在一个结构体类型的变量中,该结构体类型是由系统定义的,取名FILE
标准IO预定义的3个流
这三个文件是程序在运行的时候自动打开和关闭的,不需要用户处理
标准IO函数
// 功能
// 获取指定文件的文件指针
// 头文件
#include
// 原型
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().
// 功能
// 从指定文件读取最多一行数据头文件
#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( )的不安全性,一般建议使用前者。
char *sgets(char *str,int len){//安全gets
fgets(str,len,stdin);
if(str[strlen(str)-1]=='\n'){
str[strlen(str)-1]='\0';
}
return str;
}
// 功能
// 从指定文件读取若干个数据块
// 头文件
#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()来加以进一步判断。
// 功能
// 设置指定文件的当前位置偏移量
// 头文件
#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);
// 功能
// 将格式化数据写入指定的文件或者内存
// 头文件
#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 长双精度浮点数
#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;
}