IO输入输出及标准IO函数
【1】什么是IO
#include <stdio.h>
input:输入,从外部存储设备输入到内存中
output: 输出,从内存输出到外部存储设备。
> 存储设备:
>
> 外部存储设备,硬盘
>
> 内存:SDROM DDR4;
总结:数据从外部存储设备到内存,内存到外部存储设备的流动
【2】IO分类
1.文件IO
文件IO:由操作系统提供,与操作系统绑定,又称之为系统调用
| | windows | linux |
| ---- | ---------- | ----- |
| | file_read | read |
| | file_write | write |
注意:
1. 文件IO的复用性,可移植性较低
2. 文件IO涉及到cpu从用户空间切换到内核空间,C代码调用汇编语言等等操作,是一个**耗时的操作**,所以应该尽量减少文件IO的使用。
2.标准IO
标准IO:根据ANSI标准对文件IO进行二次封装,
printf();
if(OS == windows)
{
file_write;
}
else if(OS == Linux)
{
write;
}
作用:
1. 提高代码的复用性和可移植性;
2. 提高了输入输出的效率;
设置了一个缓冲区,缓冲区满或者满足一定条件后,调用文件IO,陷入内核,由内核完成对文件的输入输出,大大减少了对文件IO的使用。
2. 标准IO
【1】流和流指针
流(stream):将数据一个一个移入或者移出缓冲区的形式,称之为字节流;
流指针(FILE*):每打开一个文件,都会在内存中申请一片空间(缓冲区);
管理这片空间的变量都存储在FILE结构体中,FILE结构体由系统定义好了,我们使用即可;
1. FILE结构体成员
> vi -t指令 查找系统定义好的数据类型 和 变量 宏
>
> 1)sudo apt-get install ctags
>
> 2)cd /usr/include/ 如果只需要查看标准库中的内容
>
> 3)sudo ctags -R
>
> 4)在家目录的.vimrc中添加 set tags+=/usr/include/tags
>
> 追代码:
>
> ctrl + 鼠标左键
>
> 或者 左键选中要追的代码 ctrl + ]
>
> ```c
> $ vi -t FILE
> typedef struct _IO_FILE FILE;
> ctrl + 鼠标左键点击 _IO_FILE
> ```
```c
struct _IO_FILE {
char* _IO_buf_base; /* Start of reserve area. */ 缓冲区的起始地址
char* _IO_buf_end; /* End of reserve area. */ 缓冲区的结束地址
int _fileno; 文件描述符
}
```
2. 标准输入输出流
在main函数启动之前。系统会默认打开三个流指针;
```
stdin 标准输入流指针 从终端读取数据
stdout 标准输出流指针 将数据输出到终端上
stderr 标准错误输出流指针
```
3. man手册
$man man 查看man手册
```c
1 可执行程序或 shell 命令
2 系统调用(内核提供的函数) 文件IO
3 库调用(程序库中的函数) 标准IO
man 手册默认会从第一卷开始查找,
【2】标准IO函数
1. 常见的标准IO函数
fopen / fclose 打开/关闭一个文件
fprintf / fscanf
fputc / fgetc
fgets / fputs
fwrite / fread
fseek 修改文件偏移量
1)fopen
功能:打开一个文件;
头文件:
#include <stdio.h>
原型:
FILE *fopen(const char *pathname, const char *mode);
参数:
char *pathname:指定要打开的文件路径+文件名;
char *mode:打开方式;
r 以读的方式打开文件;
如果文件不存在,则打开失败;
r+ 以读写的方式打开文件;
如果文件不存在,则打开失败;
w 以写的方式打开文件;
如果文件不存在则创建文件;
如果文件存在则清空文件;
w+ 以读写的方式打开文件;
如果文件不存在则创建文件;
如果文件存在则清空文件;
a 以写的方式打开文件;
如果文件不存在则创建文件;
如果文件存在则以追加的方式写;
a+ 以读写的方式打开文件;
如果文件不存在则创建文件;
如果文件存在则以追加的方式写;
返回值:
成功,返回流指针;
失败,返回NULL,并设置错误码(errno);
例子:
FILE* fp = fopen("./1.txt", "r");
2)perror
功能:根据错误码errno,显示不同的错误信息;
头文件:
#include <stdio.h>
原型:
void perror(const char *s);
参数:
char *s:用于提示的字符串;
#include<errno.h>
errno:本质上是一个全局变量,对应了各种错误,perror就是根据errno打印错误信息的
cd /usr/include/asm-generic/
例子:
perror("fopen");
3)fclose
功能:关闭文件,销毁缓冲区;
头文件:
#include <stdio.h>
原型:
int fclose(FILE *stream);
参数:
FILE *stream:指定要关闭的流指针;
返回值:
成功,返回0;
失败,返回EOF(-1),更新errno;
4)fprintf
功能:将数据格式化输入到文件中;
头文件:
#include <stdio.h>
原型:
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
参数:
FILE *stream:指定要输出到的流指针;
char *format:格式化;
...:不定参数;
返回值:
成功,返回被打印的字节个数; >0;
失败,返回负数;
5)fscanf
功能:将文件中的数据格式化输入到内存中;
头文件:
#include <stdio.h>
原型:
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
参数:
FILE *stream:指定要输入的流指针;
char *format:格式化;
...:不定参数;
返回值:
成功,返回获取到的数据个数;
失败或者读取到文件结尾,返回EOF;
6)fputc
功能:将单个字符输出到文件中;
头文件:
#include <stdio.h>
原型:
int putchar(int c);
int fputc(int c, FILE *stream);
参数:
int c:指定要输出的字符,可以填字符类型,也可以填对应的整型;
FILE *stream:流指针;
返回值:
成功,返回输出的字符对应的整型;
失败,返回EOF;
7)fgetc
功能:从文件中获取单个字符;
头文件:
#include <stdio.h>
原型:
int getchar(void);
int fgetc(FILE *stream);
参数:
FILE *stream:流指针;
返回值:
成功,返回获取到的字符;
失败或者读取到文件结尾,返回EOF;
8)缓冲区
标准IO中所有的数据都输存储在缓冲区中,然后输出到硬件中
i. 全缓冲
**操作对象**
对普通文件进行操作(调用fopen函数打开的文件),通过FILE* fp流指针维护该缓冲区;
**大小**
4K = 4096byte = 4*1024;
//由于系统优化,当打开文件,但是不操作的时候,不会真正的申请缓冲区
fputc('a', fp);
printf("%ld\n", fp->_IO_buf_end - fp->_IO_buf_base); //4096
**刷新缓冲区的方式**
1. 缓冲区满
2. fflush函数强制刷新缓冲区
#include <stdio.h>
int fflush(FILE *stream);
3. 关闭流指针 fclose
4. 主函数调用retrun退出
5. 调用exit函数
#include <stdlib.h>
void exit(int status);
目前只要理解该函数能退出进程;
int status:随便填一个整型即可;
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
FILE* fp = fopen("./1.txt", "w");
if(NULL == fp)
{
perror("fopen");
return -1;
}
/*
//由于系统优化,当打开文件,但是不操作的时候,不会真正的申请缓冲区
fputc('a', fp);
printf("%ld\n", fp->_IO_buf_end - fp->_IO_buf_base); //4096
*/
/*
//缓冲区满
int i = 0;
while(i<4096+1)
{
fputc('a', fp);
i++;
}
*/
/*
//fflush强制刷新缓冲区
fputc('b', fp);
fflush(fp);
*/
/*
//关闭流指针
fputc('c', fp);
fclose(fp);
*/
/*
fputc('d', fp);
return 0;
*/
fputc('e', fp);
exit(0);
while(1)
sleep(1);
fclose(fp);
return 0;
}
ii.行缓冲
**操作对象**
标准输入(stdin),标准输出(stdout)
**大小**
1K = 1024byte
```c
printf("%ld\n", stdout->_IO_buf_end - stdout->_IO_buf_base);
```
**刷新缓冲区**
1. 缓冲区满
2. fflush函数强制刷新缓冲区
```c
#include <stdio.h>
int fflush(FILE *stream);
```
3. 关闭流指针 fclose
4. 主函数调用retrun退出
5. 调用exit函数
```c
#include <stdlib.h>
void exit(int status);
目前只要理解该函数能退出进程;
int status:随便填一个整型即可;
```
6. 遇到'\n'字符
7. 遇到输入函数,例如scanf fgets fscanf fgetc
iii.无缓冲
**操作对象**
标准错误输出(stderr)
**大小**
0, perror调用的就是stderr流指针
9)fputs
功能:将字符串输出到文件中;
头文件:
#include <stdio.h>
原型:
int puts(const char *s);
int fputs(const char *s, FILE *stream);
参数:
char *s:指定要输出的字符串的首地址;
FILE *stream:指定要输出到哪个流指针对应的缓冲区中;
返回值:
成功,返回非负数;
失败,返回EOF;
例子:
//打开文件:以写的方式打开
FILE* fp = fopen("./fputs.abc", "w");
if(NULL == fp)
{
perror("fopen");
return -1;
}
fputs(str, fp);
10)fgets
功能:从指定文件中获取字符串,包括空格;
头文件:
#include <stdio.h>
原型:
char *gets(char *s);
char *fgets(char *s, int size, FILE *stream);
参数:
char *s:存储获取到的字符串;
int size:指定要获取的字符串大小;最多读取size-1个字节,因为要保留'\0'位,fgets会自动填充最后的'\0'位;
注意:fgets只能识别到'\n';
假设一行有10个字节,fgets读取20个字节,实际读取10个字节,一次不会读取到下一行;
FILE *stream:指定要从哪个流指针的缓冲区中获取;
返回值:
成功,返回s,即字符串首地址;
失败或者读取到文件结尾,返回NULL;
IO输入输出及标准IO函数相关推荐
- linux 一次io大小,Linux——标准IO篇
主要知识点: 标准IO(fopen.perror.fputc.fgetc,stdin.三种缓冲区.读写偏移.fseek.ftell.fgets.fputs) [主要内容] [1]IO IO: inpu ...
- 文件IO open 与 标准 IO fopen 的对应
FILE *fp: int fd: fp = fopen("1.c", "r");等价于 fd = open("1.c",O_RDONLY) ...
- Linux操作与管理文件(多次打开同一文件,文件共享,fcntl函数,标准IO库)
1.linux系统如何管理文件 硬盘中的静态文件和inode: (1)硬盘分为两大区域:一个是硬盘内容管理表项,另一个是真正存储内容的区域.先去读取硬盘内容管理表,找到要访问的存储内容的区域,再用得到 ...
- linux read函数_浅谈Linux内核IO体系之磁盘IO
前言 Linux I/O体系是Linux内核的重要组成部分,主要包含网络IO.磁盘IO等.基本所有的技术栈都需要与IO打交道,分布式存储系统更是如此.本文主要简单分析一下磁盘IO,看看一个IO请求从发 ...
- 应用编程课程4.系统IO和标准IO的比较,自己做的一些理解,仅仅方便自己看
/* 1.注意fseek实际上是调用lseek来实现的, 比较以下标准io与文件io的区别 注意:在stream这个概念中,有三个标准流stdin.stdout.stderr,,在我们当前这个文件描述 ...
- LinuxC—标准IO与文件IO学习笔记
标准IO与文件IO 1 概述 stdio 标准IO(优先使用) sysio 系统调用IO(文件IO) sysio是直接实现用户态切换内核态,sysio和平台是有关系的,比如windows和linux, ...
- 海康工业相机功能模块-IO输入输出控制
海康工业相机功能模块sdk调用介绍 IO输入输出控制 前言 IO输入 IO输出 前言 机器视觉行业里面,相机作为最重要的图像传感器,除了主要的拍摄功能外,它也承担了一部分信号控制功能. 一方面能够接受 ...
- Linux什么是文件IO,linux中文件IO
一. linux常用文件IO接口 1.1. 文件描述符 1.1.1. 文件描述符的本质是一个数字,这个数字本质上是进程表中文件描述符表的一个表项,进程通过文件描述符作为index去索引查表得到文件表指 ...
- linux 流函数,标准IO函数库 - 二进制文件IO,流定位,创建临时文件和内存流
1 二进制IO(Binary IO) 在前一篇我们了解了逐字符读写和逐行读写函数. 如果我们在读写二进制文件,希望以此读写整个文件内容,这两个函数虽然可以实现,但是明显会很麻烦且多次循环明显效率很低. ...
最新文章
- 2.7-egrep及bash中的变量
- 因为征信原因,买房的2万定金没了
- 遥感、制图学中各种图的区别
- 计算机系统结构安全检测,信息安全体系结构安全测评实验报告.doc
- java实现定时任务 schedule_Java定时任务的三种实现方式
- 学习日志---hbase学习(最大版本查询)
- 使用RTL-SDR打开车门
- 走一波 程序员必备精品软件大全
- 解析力 (2)空间采样 和 奈奎斯特
- SRIO传输协议学习
- 禁止在计算机上玩电子游戏,如何禁止孩子玩电脑游戏防止过度沉迷影响学习成绩...
- Linux 返回根目录,返回主目录
- Web.xml 错误或异常页面配置
- vhdl timing requirements not met 错误 quartusII中
- vue字符云-------把老婆放到云端
- c语言专业教学,C语言在计算机专业中的教学.docx
- 自制FOC控制驱动器
- 前端性能优化之图片优化
- Java---子类父类继承顺序
- 操作系统原理和实践-考前最后一练