标准IO

本文详细介绍了C语言的标准I/O,包括流的概念、FILE对象、流的分类以及缓冲类型。标准I/O提供了一种在内存中使用缓冲区来提高效率的方式,减少了对系统调用的依赖。文章还列举了如fopen、fclose、fgets、fputs等常用文件操作函数,并给出示例代码展示如何读写文件。
摘要由CSDN通过智能技术生成

一、标准I/O概念
标准IO是一个标准函数包和stdio.h头文件中定义的,不依赖于系统内核,所以移植性强。

1.流的概念
在c语言中所有的IO操作只是简单的从程序移进或移出字节的工作(可以将数据的输出和输入看作是数据的流入和流出),这中字节流被称为(stream)。

2.FILE对象
文件IO函数的操作都是依赖文件描述符,打开一个文件时,就返回一个文件描述符,然后该文件描述符用于后续相关的IO操作。标准IO库的操作依赖于流(stream)进行。打开一个文件就会创建一个FILE对象,此对象是一个结构体

1>流的分类

a.文本流:在流处理过程中,所有数据以字符形式出现。所有字符以ASCII形式存储。
b.二进制流:在流处理过程中把数据当成二进制序列。
例:文本流:2021 -> 50 48 50 49
   二进制流:2021 -> 00000111 11100101  

2>一个进程启动时会打开三流stdin、stdout、stderr(标准输入,输出,错误流)

3.标准IO的文件缓冲
1>缓冲区

文件IO:读写文件时,每次操作都会执行相关系统调用,好处是直接读写实际文件,坏处是频繁的系统的调用会增加系统开销。
标准IO:系统自动的在内存中为每一个正在使用的文件开辟一个缓冲区,从内存向磁盘输出数据必须先送到缓冲区,装满缓冲区在一起送到磁盘中。
从磁盘中读数据,则一次从磁盘文件将一批数据读入到内存缓冲区中,然后再从缓冲区逐个的将数据送到程序的数据区。
【注】标准I/O可以看成在文件I/O的基础上由标准I/O库封装并维护了缓冲机制(流缓冲,都在用户空间)
	避免频繁地呼叫系统调用,尽量减少使用read/write的调用;其次缓冲区大小的设置在不同OS上是有技术的,标准库为我们做了优化选择。

2>缓冲类型(3种)

**全缓冲区**:这种缓冲区要求填满整个缓冲区后才进行I/O系统调用操作。
			对于磁盘文件通常使用全缓冲区访问。
			第一次执行I/O 操作时,ANSI 标准的文件管理函数通过调用malloc 函数获得需使用的缓冲区。linux默认大小为4096**行缓冲区**:在这种情况下,当在输入和输出中遇到换行符时,执行IO系统调用操作。
			当流涉及一个终端时(例如标准输入和标准输出),使用行缓冲区。
			因为标准I/O 库每行的缓冲区长度是固定的,只要填满了缓冲区,即使还没有遇到换行符也将执行I/O 系统调用操作。默认行缓冲区大小为1024 字节。
			
**无缓冲区**:标准I/O 库不对字符进行缓存,即对流的读写操作会立即操作实际文件。
		很多的人机交互界面要求不可全缓存。
		标准出错流stderr通常是不带缓冲区的,这使得出错信息能够尽快地显示出来。		

【注】1)不同类型设备导致关联的FILE流采用不同的缓冲类型
	 2)不同缓冲类型的缓冲大小
	 3)标准IO内部malloc的过程,实际使用时才会申请。

二、相关函数
1.fopen()函数,fclose()函数

#include <stdio.h>
FILE *fopen(const char *path, const char *mode);
参数1:文件路径名
   2:文件打开模式

FILE *fdopen(int fd, const char *mode);//需要与文件描述符相结合
FILE *freopen(const char *path, const char *mode, FILE *stream);//常用于流的重定向

int fclose(FILE *fp);//关闭打开的文件

在这里插入图片描述

2.输入/输出相关函数

输入相关:
#include <stdio.h>

//从一个指定的流中读取一个字符
int fgetc(FILE *stream);
int getc(FILE *stream);
【注】如果使用getc()函数读取一个字符时发现是文件结尾,它将返回一个特殊值EOF.
事例:
int ch; //用int类型存储EOF
FILE *fp;
fp = fopen("test.txt","r");
ch = getc(fp); //获取初始输入
while((ch = getc(fp)) != EOF)
{
	putchar(ch); //处理输入
}



//从一个指定的流中读取一个字符串
char *fgets(char *s, int size, FILE *stream);
char *gets(char *s);

//从stdin中读取一个字符
int getchar(void);

输出相关:
//向一个指定的流中输出一个字符
int fputc(int c, FILE *stream);
int putc(int c, FILE *stream);

//向stdout中输出一个字符。
int putchar(int c);

//输出字符串
int puts(const char *s);
int fputs(const char *s, FILE *stream);

程序示例,将一个文件的1/3复制到另一个文件

#include<stdio.h>

int main(int argc,const char *argv[])
{
	if( 2 > argc)
	{
		printf("argument error!\n");
		return -1;
	}

	int ch,count = 0;
	FILE *in,*out;

	if(NULL == (out = fopen(argv[1],"r")))
	{
		perror("fopen");
		return -2;
	}

	if(NULL == (in = fopen(argv[2],"w")))
	{
		perror("fopen");
		return -3;
	}
	
	
	while(EOF != (ch = getc(out)))
	{
		if((count++)%3 == 0)
		{
			if('\n' == ch)
			{
				count--;
			}
			putc(ch,in);
		}
	}

	if(0 != fclose(in) || 0 != fclose(out))
	{
		fprintf(stderr,"fclose error!\n");
	}

	return 0;
}

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值