标准IO函数的学习

标准IO函数

缓冲区

  • 只有标准IO才有缓冲区,所有的数据都先放在缓冲区中,缓冲区满或者满足一定条件后刷新缓冲区
  • 在实际生活生产过程中,代码会运行在死循环中,导致缓冲区可能不满且程序没有退出,所以必须要掌握缓冲区的刷新条件

全缓冲

  • 操作对象:手动用fopenn函数打开文件后,创建的缓冲区都是全缓冲。用FILE *类型流指针进行维护。
  • 大小:4096bytes = 4k
  • 计算大小的代码:
 fputc('a', fp);
 printf("%ld\n", fp->_IO_buf_end - fp->_IO_buf_base );
  • 刷新条件:
    (1)缓冲区满(需要再向缓冲区中多写入一个之后才能将之前的4096个刷新出来)
    (2)fflush函数,强制刷新输出流缓冲区
       #include 
       int fflush(FILE *stream);

(3)关闭流指针 (fclose)
(4)主函数调用return
(5)调用exit函数退出程序
(6)输入输出转换

行缓冲

  • 操作对象:标准输入流指针(FILE *stdin)标准输出流指针(FILE *stdout)
  • 大小:1024bytes = 1k
printf("size=%ld\n", stdout->_IO_buf_end - stdout->_IO_buf_base)
  • 刷新条件
    (1)缓冲区满(要多写一个后才能刷新前1024个)
    (2)fflush函数,强制刷新输出流缓冲区
    (3)关闭流指针 fclose
    (4)主函数调用return
    (5)调用exit函数退出程序
    (6)遇到\n字符
    (7)输入输出转换

无缓冲

  • 操作对象:标准错误输出流指针(FILE *stderr)->perror函数默认封装就是stderr流指针
  • 大小:1bytes,且只要往里存放数据,就会直接将数据刷新出来
  • 无刷新条件

fputs

  • 功能:将字符串输出到指定的文件中,fputs不会自动补充\n

  • 原型:int fputs(const char *s, FILE *stream)

  • 参数:char *s:指定要输出的字符串首地址
    FILE *stream:流指针

  • 返回值:成功返回非负数>=0;失败返回EOF;

fgets

  • 功能:从指定文件中获取字符串
    (1)最多获取size-1个字节,因为fgets函数在停止读取后,自动在有效字符的最后一个字节补上\0
    (2)会获取空格和 \n 字符
    (3)遇到 \n 字符后停止读取,且会获取 \n 字符

  • 原型:char *fgets(char *s, int size, FILE *stream)

  • 参数:char *s:存储获取到的字符串
    int size:size - 1
    FILE *stream:流指针

  • 返回值:成功返回存储数据空间的首地址;失败返回NULL;当读取到文件结尾,且没有任何数据被读取出来,返回NULL

fwrite

  • 功能:将数据的二进制形式写入到指定的文件中
    二进制形式->将数据拆分成一个一个的字节并转换成字符形式写入文件中

  • 原型:size_t fwrite(const void *ptr, size_t size, size_t nmemb,
    FILE *stream)

  • 参数:void *ptr:指定要输出的数据的首地址;(void *类型,代表任意数据类型)
    size_t size:每个数据所占的字节数大小
    sizei_t nmemb:指定要输出的数据个数:注意是个数,不是字节数
    FILE *stream:流指针

  • 返回值:成功返回成功输出的数据个数,即nememb;失败时=0或者

fread

  • 功能:将数据的二进制形式从指定文件中读取出来,转换成对应的数据

  • 原型:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

  • 参数:void ptr:指定要将数据存储到位置的首地址(void类型)
    size_t size:每个数据所占的字节数大小
    size_t nmemb:指定要读取的数据个数
    FILE *stream:流指针

  • 返回值:成功返回成功读取的数据个数:即nmemb;失败或者读取到文件结尾的时候,=0或者

fseek

  • 功能:修改文件偏移量到指定位置
  • 原型:int fseek(FILE *stream, long offset, int whence)
  • 参数:FILE *stream:指定要修改哪个文件的偏移量
    long offset:距离whence参数指定的偏移量(往前便宜填负数,往后偏移填正数)
    int whence:
    SEEK_SET,文件开头位置
    SEEK_CUR,文件当前位置
    SEEK_END,文件结尾位置
  • 返回值:成功返回0,失败返回-1,更新errno
  • 注意:
    1>若偏移量在文件开头,不能继续往前偏移
    2>若偏移量在文件结尾,可以继续往后偏移
    3>若是以w w+ r+的方式打开,往结尾后偏移10个字节后写入,则会从第10个字节写入数据,且前面空余部分会自动补充^@
    4>若是以a a+方式打开,往后偏移10个字节后写入,从文件结尾的最后一个有效字符的后面写入。

ftell

  • 功能:获取文件当前位置距离文件开头的偏移量
  • 原型:long ftell(FILE *stream)
  • 返回值:成功返回当前位置距离文件开头的偏移量;失败返回-1,更新errno
  • 将文件偏移量修改到结尾,获取文件偏移量的值,就是文件大小
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);

练习:

一、使用fgets实现计算一个文件有几行

#include 
#include 
#include 
#include 
int main(int argc, const char *argv[])
{
	FILE *fp_r=fopen("./1.txt","r");
	FILE *fp_w=fopen("./2.txt","w");
	if(NULL == fp_r)
	{
		ERRO_MES("fopen");
		return -1;
	}
	if(NULL == fp_w)
	{
		ERRO_MES("fopen");
		return -1;
	}
	char str[20]="";
	int count=0,line=0;
	while(1)
	{
		if(NULL == fgets(str,sizeof(str),fp_r))
			break;
		line++;
		fputs(str,fp_w);
		count+=strlen(str);
	}
	printf("一共有%d个字节 有%d行\n",count,line);
	fclose(fp_r);
	fclose(fp_w);
	fp_r=fp_w=NULL;
	return 0;
}

二、用fread和fwrite实现文件拷贝

#include 
#include 
#include 
int main(int argc, const char *argv[])
{
	FILE *fp_r=fopen("read.txt","r");
	if(NULL == fp_r)
	{
		perror("fopen");
		return -1;
	}
	FILE *fp_w=fopen("write.txt","w+");
	if(NULL == fp_w)
	{
		perror("fopen");
		return -1;
	}
	char str[42]="";
	while(1)
	{
		size_t num=fread(str,sizeof(str)-1,1,fp_r);
		if(0 == num)
			break;
		fwrite(str,sizeof(str)-1,1,fp_w);
	}
	return 0;
}

三、思维导图

你可能感兴趣的:(学习)