标准IO库的介绍

标准IO库的介绍

标准IO库能够处理很多的细节,例如缓冲区的分配,以优化长度执行I/O等。这些处理使用户不必担心如何选择使用正确的块长度,这就方便了用户的使用。

1.1 流和FILE对象

所有的IO函数都是针对文件描述符的,每当打开一个文件时,就返回一个文件描述符,然后这个文件描述符就用于后面的IO操作。对于标准IO库,它的操作是围绕流(stream)来进行的。当用标准IO打开或者创建一个文件时,我们就使一个流与一个文件进行关联起来了。标准IO文件流可以用于单字节或者多字节(宽)字符集。流的定向决定了所读写字符是单字节还是多字节的,当流被创建时,它并没有定向,可以在为定向的流上使用一个多单字节或者多字节IO函数,就可以把该流的定向设置为字节定向或者宽定向。只有两个函数可以改变流的定向。分别是freopen函数和fwide函数。前者清楚流定向,后者设置流定向。

#include <stdio.h>
FILE *freopen(const char *path, const char *mode, FILE *stream);
//filename 要打开的文件名称
//mode 文件访问模式,模式如下:r,w,a等
//stream 指向FILE对象的指针,该FILE对象标识了要被重新打开的流
#include <wchar.h>
int fwide(FILE *stream, int mode);
//如果流是宽定向,则返回正值,如果是字节定向,返回负值,未定向则返回

当我们打开一个流时,标准IO函数fopen返回一个指向FILE对象的指针,该对象通常是一个结构体。它包含了标准IO库为管理该流所需要的所有信息。包含的信息:实际IO的文件描述符,指向用于该流缓冲区的指针,缓冲区的长度,当前在缓冲区的字符数以及出错标志等。为了引入一个流,需要将FILE指针作为参数传递给每一个标准IO函数。我们把FILE对象的指针叫做文件指针。

1.2 标准输出,标准输入,标准出错

对一个进程预定义了三个流,这三个分别是标准输入,标准输出,标准出错,他们可以自动地被进程使用,这三个标准IO流通过预定义文件指针stdin,stdout和stderr加以引用。他们同样定义在<stdio.h>中。

1.3 缓冲

标准IO使用缓冲的目的是避免多次使用read和write,标准IO提供了三种类型的缓冲:
1、全缓冲:填满标准IO缓冲区后才可以进行实际IO操作,对于驻留在磁盘上的文件通常是采用全缓冲的,在一个流执行第一次IO操作的时候,相关标准IO函数通常调用malloc获得需要的缓冲区。
2、行缓冲:当在输入输出中遇到换行符时,标准IO库执行IO操作。这允许我们一次输出一个字符(用标准IO函数fputc),但只有在写了一行之后才进行实际的IO操作。当流涉及到一个终端时,通常使用行缓冲。
3、不带缓冲:标准IO不对字符进行缓冲存储,例如,如果用标准IO函数fputs写15个字符到不带缓冲的流中,则函数很有可能使用write系统调用函数将这些字符立即写道相关联的打开文件上。
对于给定的任何一个流,如果我们并不喜欢这些系统默认的情况,则可以调用下面的函数更改缓冲类型:

#include <stdio.h>
void setbuf(FILE *stream, char *buf);
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
//若果成功,则返回0,出错就返回非0值

2.1 打开流

下面有三个函数打开一个标准IO流:

#include <stdio.h>
FILE *fopen(const char *path, const char *mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream);

1、fopen打开一个指定的文件;
2、fdopen打开一个现有的文件描述符,并使一个标准的IO流与该描述符相结合;
3、在一个指定的流上打开一个指定的文件,如果该流已经打开,则先关闭该流,如果该流已经定向,则freopen清除该定向,此函数一般用于将一个指定的文件打开为一个预定义的流:标准输入输出,标准出错。

2.2 读和写流

一旦打开了流,就有三种不同类型的非格式化IO进行选择,对其进行读写操作:
1、每次一个字符的IO,一次读或者写一个字符,如果流失带缓冲的,则标准IO函数会处理所有缓冲。
2、每次一行的IO,如果每次想要读或者写一行,则使用fgets和fputs。每行都以一个换行符作为终止。每当调用fgets时,应说明应当处理的最大行长。
3、直接IO,fread和fwrite函数支持这种类型的IO。每次IO操作读或者写某种数量的对象,而每个对象具有指定的长度。这两个函数常用语从二级制文件中每次读或者写一个结构。

2.2.1输入函数

以下三个函数可用于一次读一个字符:

#include <stdio.h>
int getc(FILE *stream);
int fgetc(FILE *stream);
int getchar(void);

三个函数的返回值:如果成功则返回下一个字符,如已经达到文件结尾,或者出错,则返回EOF。

2.2.2输出函数

对应于上面的输入函数,就有一个与之对应的输出函数:

#include <stdio.h>
int putc(int c, FILE *stream);
int fputc(int c, FILE *stream);
int putchar(int c);

三个函数返回值:成功返回c,如果出错则返回EOF。
写函数fputc的举例,我们创建一个1.txt文件,并每次写入一个字符:

#include <stdio.h>
int main(int argc, char const *argv[])
{
	FILE* fp = fopen("/home/kwb/Desktop/01stdio/sec1/1.txt","w");
	if(NULL == fp)
	{
		printf("fopen err\n");
		return 1;
	}
	fputc('H',fp);
	fputc('e',fp);
	fputc('l',fp);
	fputc('l',fp);
	fputc('o',fp);
	fputc('!',fp);
	fputc(fp);
	return 0;
}

编译运行:
在这里插入图片描述在这里插入图片描述
读文件,每次读一个字符,读上面创建的文件:

#include <stdio.h>
int main(int argc, char const *argv[])
{
	FILE* fp = fopen("./1.txt","r");
	if(NULL == fp)
	{
		printf("fopen err\n");
		return 1;
	}
	//写文件
	/*fputc('H',fp);
	fputc('e',fp);
	fputc('l',fp);
	fputc('l',fp);
	fputc('o',fp);
	fputc('!',fp);*/
	//读文件
	int c = fgetc(fp);
	printf("%c",c);
	c = fgetc(fp);
	printf("%c",c);
	c = fgetc(fp);
	printf("%c",c);
	fclose(fp);
	return 0;
}

执行结果:
在这里插入图片描述
这样去读文件肯定是有问题的,不能这么读,我们使用EOF这个宏去判断,文件是不是读完了。

#include <stdio.h>
int main(int argc, char const *argv[])
{
	FILE* fp = fopen("./1.txt","r");
	if(NULL == fp)
	{
		printf("fopen err\n");
		return 1;
	}
	while(1)
	{
		int c = fgetc(fp);
		if(EOF == c)
		{
			break;
		}
		printf("%c",c);
	}
	fclose(fp);
	return 0;
}

执行结果:
在这里插入图片描述

总结

前面介绍了文件的读写操作。对其有了基本的了解,更多的操作与注意事项后续继续。。。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值