目录
一、认识IO
1.IO的种类
标准IO | 文件IO |
---|---|
ANSI C (标准C库) | posix (可移植操作系统的标准) |
库函数 | 系统调用 |
系统调用:从用户空间到内核空间的切换过程,不同的操作系统系统调用的接口是不同的。只要从用户空间到内核空间了就要发生一次系统调用,效率比较低。系统调用没有缓冲区。
库函数:库函数的平台的通用新更强,库函数有缓冲区,效率比系统调用高。库函数=缓冲区+系统调用
2.缓冲区
2.1缓冲区的种类
全缓存:和文件相关的缓冲区就是全缓存 (fp 4096字节)
行缓存:和终端相关的缓冲区是行缓存 (stdin stdout 1024字节)
不缓存:标准出错没有缓冲区(stderr 0字节)
2.2缓冲区的刷新机制
2.2.1行缓冲区的刷新机制
1.行缓存遇到’\n’字符会刷新缓冲区
2.程序执行结束,也会刷新行缓冲区
3.当输入和输出发生切换的时候也会刷新缓冲区
4.当关闭文件指针的时候也会刷新缓冲区
5.fflush主动刷新缓冲区
6.如果(行)缓冲区满了,会刷新缓冲区
2.2.2全缓冲区的刷新机制
1.程序执行结束,也会刷新全缓存
2.输入输出发生切换的时候,会刷新全缓存
3.关闭文件指针,会刷新全缓存
4.fflush主动刷新缓冲区
5.全缓存满,也会刷新缓冲区
3.常用函数接口种类
标准IO:printf scanf fopen fclose fread fwrite fgetc fputc fgets fputs…
文件IO:open read write close…
二、标准IO
1.什么是FILE
标准IO库的操作依赖于流(stream)进行。打开一个文件就会创建一个FILE对象,返回一个FILE**的指针(文件指针)此对象是一个结构体。在这个结构体中记录所有的关于文件的信息,以后对文件的操作通过FILE*来完成。
/usr/include/
ctags -R //创建索引
vi -t FILE //查找FILE实现的位置
typedef struct _IO_FILE FILE;
struct _IO_FILE {
char* _IO_buf_base; //缓冲区的首地址
char* _IO_buf_end; //缓冲区的结束地址
...
};
在一个正在执行的程序中,已经创建了三个FILE的指针,如下:
stdin: 标准输入 (scanf)
stdout 标准输出 (printf)
stderr: 标准出错
2.什么是错误码
在文件IO或标准IO相关接口被调用的时候,如果出错了,操作系统会给应用程序返回错误码
#include <string.h>
char* strerror(int errnum);
功能:根据错误码转换错误信息
参数:
@errnum:这个是错误码,包含
#include <errno.h>
extern int errno;
返回值:错误信息字符串
void perror(const char *s);
功能:打印错误码对应的信息
参数:
@s:用户附加的信息
返回值:无
strerror的使用
#include <stdio.h>
#include <errno.h>
#include <string.h>
//extern int errno;
int main(int argc,const char * argv[])
{
//定义文件指针
FILE *fp;
//以只读的方式打开文件,文件不存在会报错
fp = fopen("./hello.txt","r");
if(fp == NULL){
printf("%s\n",strerror(errno));
return -1;
}
fclose(fp);
return 0;
}
perror的使用
#include <stdio.h>
int main(int argc,const char * argv[])
{
//定义文件指针
FILE *fp;
//以只读的方式打开文件,文件不存在会报错
fp = fopen("./hello.txt","r");
if(fp == NULL){
perror("open hello.txt");
return -1;
}
fclose(fp);
return 0;
}
3.fopen / fclose
3.1fopen
功能:使用标准IO打开文件
#include <stdio.h>
FILE* fopen(const char *pathname, const char *mode);
参数:
@pathname: 路径/文件名 “./hello.txt”
@mode:打开文件的方式 “r”
r:以只读的方式打开文件,将文件中的光标定位在文件的开头
r+:以读写的方式打开文件,将文件中的光标定位在文件的开头
w:以只写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空,将光标定位在开头
w+:以读写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空,将光标定位在开头
a:以追加(结尾写)的方式打开文件,如果文件不存在就创建文件,将光标定位在文件的结尾
a+:以读和追加(结尾写)的方式打开文件,如果文件不存在就创建文件,如果读从开头读,写在文件的结尾写
返回值:成功返回文件指针,失败返回NULL,置位错误码
实例:
#include <stdio.h>
int main(int argc,const char * argv[])
{
//定义文件指针
FILE *fp;
//以追加的方式打开文件,如果文件存在,不会清空(追加)
if(NULL == (fp = fopen("./hello.txt","a")))
{
printf("create file error\n");
return -1;
}
return 0;
}
3.2fclose
功能:关闭文件
int fclose(FILE* stream);
参数:
@stream:文件指针
返回值:成功返回0,失败返回EOF(end of file),并置位错误码
实例:
#include <stdio.h>
int main(int argc,const char * argv[])
{
FILE *fp;
//以只写的方式打开文件
fp = fopen("./hello.txt","w");
if(fp == NULL){
printf("create file error\n");
return -1;
}
//关闭文件
if(fclose(fp)<0){
printf("close file error\n");
return -1;
}
return 0;
}
4.fgetc / fputc
4.1fgetc(getc,getchar)
功能:从文件中读取一个字符
int fgetc(FILE *stream);
参数:
@stream:文件指针
返回值:成功返回字符的ascii,读取文件的结尾EOF,失败返回error
实例:
#include <stdio.h>
int main(int argc,const char * argv[])
{
FILE *fp;
fp = fopen("./01fopen.c","r");
if(fp == NULL){
perror("fopen error");
return -1;
}
int i=0;
while(i++<30){
printf("%c",fgetc(fp));
}
puts("");//换行
fclose(fp);
return 0;
}
4.2fputc(putc,putchar)
功能:向文件中写一个字符
int fputc(int c, FILE *stream);
参数:
@c:被写字符的ascii
@stream:文件指针
返回值:成功返回ascii,失败返回EOF
实例:
#include <stdio.h>
int main(int argc, const char *argv[])
{
FILE *fp;
fp = fopen("./test.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
fputc('h', fp);
fputc('e', fp);
fputc('l', fp);
fputc('l', fp);
fputc('o', fp);
fclose(fp);
return 0;
}
5.fgets / fputs
5.1fgets(gets)
功能:从文件指针中读取一个字符串
char *fgets(char *s, int size, FILE *stream);
参数:
@s:用来存储读取到字符的首地址
@size:读取的大小(最多读取size-1)
@stream:文件指针
返回值:成功返回s,失败返回NULL
注:遇到换行或者EOF的停止读取,换行符也会被读取到s的缓冲区中,并且在换行符之后存储一个'\0'结束符
实例:
#include <stdio.h>
#include <string.h>
int main(int argc,const char * argv[])
{
char buffer[1024];
printf("input string > ");
fgets(buffer,sizeof(buffer),stdin);
//将读取到的换行符设置为'\0'
//hello\n
//buffer=hello'\n''\0'
//strlen(buffer)=6
//buffer[5]='\0'
buffer[strlen(buffer)-1]='\0';
printf("%s\n",buffer);
return 0;
}
5.2fputs(puts)
功能:将s字符串中的内容写入到文件中
int fputs(const char *s, FILE *stream);
参数:
@s:首地址
@stream:文件指针
返回值:成功返回写入的字符的个数,失败返回EOF
实例:
#include <stdio.h>
int main(int argc,const char * argv[])
{
FILE*fp;
//向标准输出中写入字符串
fputs("helloworld",stdout);
//向标准出错中写入字符串
fputs("helloworld",stderr);
if ((fp = fopen("hello.txt", "w")) == NULL)
{
perror("fopen file error");
return -1;
}
fputs("i love china",fp);
fclose(fp);
return 0;
}
今天太晚了,未完待续…