C语言标准IO

文章目录

        • 一、文件指针
          • 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
            • 注意:
          • 8、格式控制符
          • 9、标准IO,实现拷贝文件

一、文件指针

FILE指针:每个被使用的文件都在内存中开辟出一个区域,用来存放文件的相关信息,这些信息是保存在一个结构体类型的变量中,该结构体类型是由系统定义的,取名FILE

C语言标准IO_第1张图片

标准IO预定义的3个流

​ 这三个文件是程序在运行的时候自动打开和关闭的,不需要用户处理

C语言标准IO_第2张图片

标准IO函数

1、fopen打开文件,得到这个文件的文件指针
// 功能
// 获取指定文件的文件指针
// 头文件
#include 
// 原型
FILE*fopen(const char *path, const char*mode);
// 参数
// path:即将要打开的文件
// mode:
// "r:以只读方式打开文件,要求文件必须存在。
// "r+":以读写方式打开文件,要求文件必须存在。
// "w":以只写方式打开文件,文件如果不存在将会创建新文件,如果存在将会将其内容清空。
// "w+”︰以读写方式打开文件,文件如果不存在将会创建新文件,如果存在将会将其内容清空。
// "a":以只写方式打开文件,文件如果不存在将会创建新文件,且文件位置偏移量被自动定位到文件末尾(即以追加方式写数据)。
// "a+":以读写方式打开文件,文件如果不存在将会创建新文件,且文件位置偏移量被自动定位到文件末尾(即以追加方式写数据)。
// 返回值 成功 文件指针 ;失败 NULL
2、fclose关闭文件

C语言标准IO_第3张图片

3、每次一个字符的读写fgetc,fputc,feof,ferror

C语言标准IO_第4张图片

// 功能
讲一个字符写入一个指定的文件
// 头文件
#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可能已达末尾,或者遇到错误

C语言标准IO_第5张图片

注意:

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]='\0';
	}
	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指定的自定义缓冲区中读入数据。

8、格式控制符
// 格式控制符
// %d 			有符号十进制整型数
// %u 			无符号十进制整型数
// %o 			无符号八进制整型数
// %x 			无符号十六进制整型数
// %c			字符
// %s 			字符串
// %f 			计数法单精度浮点数
// %e 			科学技术法单精度浮点数
// %p			指针
// %.5s			取字符串的前5个字符
// %.5f			取单精度浮点数小数点后5位小数
// %5d			位宽至少为5个字符,右对齐
// %-5d			位宽至少为5个字符,左对齐
// %hd 			半个有符号数十进制整型数
// %hhd			半半个有符号数十进制整型数
// %lf /%le		双精度浮点数
// %Lf / %Le	长双精度浮点数
9、标准IO,实现拷贝文件
#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;
}

你可能感兴趣的:(Linux-c,c语言,c++,开发语言)