1.1什么是IO?
I: input
O:output
输入:从键盘将数据输入到内存中
输出:从内存将数据拷贝到显示屏上
对IO更深层次的理解:
Linux下一切皆文件
输入:从文件将数据输入到内存中
输出:从内存将数据拷贝到文件中
1.2 标准IO
标准IO 由ANSI C标准说明
(1)可以跨平台,既可以在windows下使用,又可以在linux上使用
(2)库函数
(3)有缓冲区
(4)通过文件流指针来进行操作
1.3相关概念
系统调用:
系统:os
调用:调用函数
系统调用:调用操作系统提供的函数
系统调用:os提供给应用程序的接口(函数)
1.4缓冲区
作用:减少系统调用的次数
全缓存:当缓冲区满、程序结束、强制刷新缓冲区时会刷新缓冲区
行
行缓存:当缓冲区满、程序结束、强制刷新缓冲区、遇到换行符时会刷新缓冲区
强制刷新缓冲区:
遇到换行符时:
不缓存:没有缓存区,直接输出,程序运行之后会默认打开三个文件标准输入、标准输出、标准出错,对应的流指针分别为stdin、stdout、stderror(standard)
1.5 文件
一组相关数据的有序集合
文件名:这组集合的名称
文件的类型:
1、普通文件
a.ASCII码文件(文本文件) b、二进制文件
2、目录文件 d
3、块设备文件 b
4、字符设备文件 c
5、链接文件 l
6、管道文件 p
7、套接字文件 (socket)s
1.6 流和FILE指针
流:字节的进进出出
流的分类:
文本流:数字2001对应的文本流为‘2‘ ’0‘ ’0‘ ’1‘(50 48 48 49)
二进制流:数组2001 对应的二进制流00000111 11010001
FILE指针:每个被使用的文件都会在内存中开辟一空间,用来保存文件的相关信息,这些信息保存在结构体中取名为FILE。
注意:标准IO中所有的操作都是围绕流来操作的,流用FILE *来描述
1.6标准io相关函数
文件操作步骤:
1.6.1打开文件:
FILE *fopen(const char *pathname,const char *mode);
函数功能:打开文件
参数1:要打开文件的路径
参数2:打开方式
r:以只读的方式打开文件,文件不存在否则出错
r+:以可读可写的方式打开文件,文件不存在否则出错
w:以只写的方式打开文件,文件不存在则新建文件,文件存在清空文件中的内容
w+:以可读可写的方式打开文件, 文件不存在则新建文件,文件存在清空文件中的内容
a:以追加的方式打开只写的文件,文件不存在则新建,文件存在则追加到末尾
a+:以追加的方式打开可读可写文件,文件不存在则新建,文件存在则追加到末尾
返回值:成功返回已打开的文件流指针,失败返回NULL
1.6.2操作文件(read/write):
读写方式:按字符读写、按行读写、按块读写
1.6.2.1 按字符读写:
getchar()、putchar()只能从键盘输入
fgetc()、fputc() 既能从键盘输入、又能从文件输入
int fgetc(FILE *stream)
功能:从指定的流中读取一个字符
参数:fopen的返回值,已经打开的文件流指针
返回值:成功返回读到的ASCII值,失败or 读到文件末尾 -1
int fputc(int c , FILE *stream)
功能:向指定的流中输出一个字符
参数1:要输出的字符
参数2:fopen的返回值,已经打开的文件流指针
返回值:成功返回ASCII码,失败返回-1
案例:实现cp
int feof(FILE *stream);
函数功能:判断文件是否到达文件末尾
参数:文件流指针
返回值:没有到达文件末尾就一直为0,到达文件末尾就不为0了
//非0为真,可以处理二进制文件
注意:feof即可以判断是否到达文本文件的末尾,也可以判断是否到达二进制文件的末尾
1.6.2.2按行读写
gets()、puts()
fgets()、fputs()
char *fgets(char *s,int size, FILE *stream)
函数功能:从指定的流中读取一串字符
参数1:读到的内容的空间的首地址
参数2:读多大
参数3:文件流指针
返回值:成功返回读到的内容空间的首地址,是否或者读到文件的末尾返回null
从键盘上读入
总结:
(1)fgets读取内容会将换行符业也读入
(2)fgets最多读取size-1个
fgets和gets的区别:
fgets比gets更安全只能读取size-1个,gets不会做越界检查
int fputs(const char *s,FILE *stream)
功能:指定输出到stream文件
参数1:要输入字符串的首地址
参数2:要输入字符串的文件
返回值:成功返回非负整数,失败返回-1 (EOF)
总结fputs和puts的区别:
puts会自动添加换行符,而fputs不会
1.6.2.4 按块读写
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:按块读写
参数1:读到内容空间的首地址
参数2:块的大小 一般设置为一个字节
参数3:块的个数
参数4:文件流指针
返回值:成功返回块的个数,失败返回-1
size_of fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
功能:按块写数据
参数1:要写的内容空间的首地址
参数2:要写的块的大小
参数3:块的个数
参数4:文件流个数
返回值:成功返回块的个数,失败返回-1
用feof(FILE *fd)
1.6.2.5 结构体的读写:
fread(&stu,1,sizeof(stu),fr);
fwrite(&str,1,sizeof(stu),fr);
1.6.2.6 ftell
long ftell(FILE *stream);
函数功能:获取当前文件的位置
参数:文件流指针
返回值:成功当前文件的位置,失败返回-1
注意:可以读取当前文件的大小
1.6.3关闭文件:
int fclose(FILE *stream)
参数:fopen的返回值,已经打开文件的流指针
返回值:成功返回0,失败返回EOF(-1)
注意:EOF(end of file)只能判断是否到达文本文件的末尾,不能判断二进制文件//文本文件ASCII没有-1,当遇到-1时说明以在文件末尾
二进制文件中有-1,-1可能为文件中的内容所有不判断二进制文件
1.7 printf和perror的区别:
perror会打印错误信息,printf不会
1.8 fseek rewind函数
int fseek(FILE *stream,long offset,int whence)
功能:获取流的位置
参数1:文件流指针
参数2:偏移量
参数3:偏移的位置
返回值:成功
SEEK_SET 0 //文件开头
SEEK_CUR 1 //文件当前位置
SEEK_END 2 //文件末尾
案例:fseek(fp,10,SEEK_CUR)从当前位置向后偏移10个字节
fseek(fp,0,SEEK_SET);//文件开头
rewind
void rewind(FILE *stream)
功能:返回流的头部
参数1:文件流
返回值:空
ftell(FILE *stream)
功能:当前指针之前(包括自己)所包含字节数
参数1:文件流