【DAY22】Linux软件编程基础:IO编程(函数接口)详解
I:input O: output
一、概念
1.一切皆是文件
io操作对象是文件
b block 块设备 存储设备 按块扫描设备信息
c character 字符设备文件 键盘、鼠标、终端
按字符扫描设备信息
d directory 目录文件 存放文件信息的文件夹
- 普通文件
l link 链接文件 将文件链接向另一个文件
s socket 套接字文件 进程间通信
p pipe 管道文件 进程间通信
2.IO接口分类
| 分类 | ||
| 普通文件 | 标准IO | 有缓存IO |
| 设备、通信文件 | 文件IO | 无缓存IO |
| 目录文件 | 目录IO |
二、标准IO
1.标准IO头文件 #include
2.普通文件
ASCII码文件:文件中存放的内容均为能够在终端显示的ASCII码字符
- 代码、文本文件
二进制文件:存放二进制数据的文件
- 音视频、图片、压缩包..
注意:ASCII码文件是一种特殊的二进制文件
3.文件操作
- 打开文件: fopen
- 读写文件
- 关闭文件:fclose
4.默认打开的流
- stdin 标准输入流
- stdout 标准输出流
- stderr 标准错误流
5.缓存类型
1.全缓存:4096 (4K)
1. 缓存区满刷新缓存区
2. 刷新条件:
- 1. 缓存区满刷新
- 2. 程序结束或是fclose刷新
- 3. 使用fflush函数强制刷新
- 3. 与文件建立的缓存是全缓存
- 4. fopen
2. 行缓存:1024 (1K)
1. 遇到 刷新缓存区
2. 刷新条件:
- 1. 缓存区满刷新
- 2. 程序结束或是fclose刷新
- 3. 使用fflush函数强制刷新
- 4. 遇到 刷新
3. 与终端建立的缓存都是行缓存
4. stdin、stdout
3. 不缓存 0k
1. 没有缓存区直接刷新
2. 用于错误处理或者人机交互
stderr
6.函数接口
1.fopen
原型:FILE *fopen(const char *pathname, const char *mode);
功能:打开文件并与文件建立流
参数:
pathname:打开文件的路径
mode:打开的方式
- r: 只读 文件不存在 报错 ; 文件存在 只读打开
- r+:读写 文件不存在 报错 ; 文件存在 读写打开
- w: 只写 文件不存在 创建 ; 文件存在 清0只写打开
- w+:写读 文件不存在 创建 ; 文件存在 清0写读打开
- a: 追加只写 文件不存在 创建; 文件存在 追加只写打开
- a+:追加读写 文件不存在创建; 文件存在 追加读写打开
返回值:
成功返回建立的流的空间的首地址
失败返回NULL
2.fclose
原型:int fclose(FILE *stream);
功能:关闭流
参数:
stream:文件流指针
返回值:
成功返回0,失败返回EOF
3.fputc
int fputc(int c, FILE *stream);
功能:
向流中写入一个字符
参数:
stream:文件流指针
c:要写入的字符的ASCII码值
返回值:
成功返回写入字符的ASCII码值
失败返回EOF(-1)
//利用fputc函数接口,执行代码后,会创建putfile文件,并写入字符串

4.fgetc
int fgetc(FILE *stream);
功能:
从流中读取下一个字符
参数:
stream:文件流指针
返回值:
成功返回读到字符的ASCII码值
或者读到文件末尾返回EOF
//利用fgetc函数接口,执行下述代码后,读取文件file.txt中的内容并打印在终端

char ch = 0;
ch = getchar(); 等价于 ch = fgetc(stdin)
putchar(ch); 等价于 fputc(ch, stdout)
5.fputs
int fputs(const char *s, FILE *stream);
功能:
向流中写入一串字符
参数:
s:字符串的首地址
stream:文件流指针
返回值:
成功返回非负数
失败返回EOF
fputs和puts不完全等价
- puts会多打印
- fputs不会多打印
6.fgets
har *fgets(char *s, int size, FILE *stream);
功能:
从流中接收一串字符,字符长度大于0小于size,遇到 或者EOF返回
参数:
s:存放字符串空间的首地址
size:最多读取字符个数
stream:文件流指针
返回值:
成功返回存放字符串空间的首地址
失败或者读到文件末尾返回NULL
gets和gets不完全等价
- gets去掉从终端接收的
- fgets不会去掉从终端接收的
如果想用fgets实现gets功能,参考如下形式:
fgets(str, sizeof(str), stdin);
str[strlen(str)-1] = ' ';
//利用fgets和fputs函数接口,从文件file1读取内容,并复制到文件file2中
#include
int main(void)
{
int ch = 0;
char str[256] = {0};
char *pstr = NULL;
FILE *p1 = NULL;
FILE *p2 = NULL;
p1 = fopen("file1","r"); //file1 存在,有内容
p2 = fopen("file2","w+"); //会覆盖原file2的内容文件
if(NULL == p1)
{
perror("fail to fopen");
return -1;
}
if(NULL == p2)
{
perror("fail to fopen");
return -1;
}
while(1)
{
pstr = fgets(str, sizeof(str), p1);
if(NULL == pstr)
{
break;
}
fputs(pstr,p2);
}
fclose(p1);
fclose(p2);
return 0;
}
7.fprintf
int fprintf(FILE *stream, const char *format, ...);
功能:
向流中写入格式化的字符串
参数:
stream:文件流指针
format:字符串首地址
...
返回值:
成功返回打印的字符个数
失败返回负数
8.fscanf
int fscanf(FILE *stream, const char *format, ...);
功能:
从流中读取格式化的字符串
参数:
stream:文件流指针
format:接收字符串的形式
返回值:
返回匹配项的个数
失败或者读到文件末尾返回EOF
// 利用fscanf读取文件中的内容,并打印在终端上
#include
int main(void)
{
int a[6] = {0};
int i = 0;
int num = 0;
FILE *fp = NULL;
fp = fopen("file","r");
if(NULL == fp)
{
perror("fail to fopen");
return -1;
}
while(1)
{
num = fscanf(fp, "%d", &a[i]);
if(EOF == num)
{
break;
}
i++;
}
fcolse(fp);
for(i = 0; i<6; i++)
{
printf("%d", a[i]);
}
printf("
");
return 0;
}

9. fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
向流中写入ptr指向的nmemb个对象,每个对象size字节
参数:
- ptr:存放写入对象空间的首地址
- size:写入的对象的大小
- nmemb:写入对象的个数
- stream:文件流指针
返回值:
成功返回写入对象的个数
出错返回0
10. fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
从流中读取nmemb个对象,每个对象size字节,存放到ptr指向的空间中
参数:
- ptr:存放数据空间首地址
- size:对象的大小
- nmemb:对象的个数
- stream:文件流指针
返回值:
成功返回实际读到对象的个数
失败或读到文件末尾返回0
//利用fread和fwrite实现一个图片文件的拷贝
#include
int main(void)
{
char src[256] = {0};
char dst[256] = {0};
char ch[4096] = {0};
FILE *ps = NULL;
FILE *pd = NULL;
size_t ret = 0;
printf("please put srcrode:
");
gets(src);
printf("please put dstrode:
");
gets(dst);
ps = fopen(src, "r");
pd = fopen(dst, "w");
if(NULL == ps)
{
perror("fail to fopen");
return -1;
}
if(NULL == pd)
{
perror("fail to fopen");
return -1;
}
while(1)
{
//每次读一个字节读4096次
ret = fread(ch, 1, sizeof(ch), ps);
if(0 == ret)
{
break;
}
fwrite(ch, 1, sizeof(ch), pd);
}
fclose(ps);
fclose(pd);
return 0;
}
11. fseek
int fseek(FILE *stream, long offset, int whence);
功能:
重定位流的偏移量
参数:
- stream:文件流指针
- offset:文件偏移量
whence:
- SEEK_SET 文件开头
- SEEK_CUR 文件当前位置
- SEEK_END 文件末尾
返回值:
成功返回0
失败返回-1
12. ftell
long ftell(FILE *stream);
功能:
返回流的偏移量
13. rewind
void rewind(FILE *stream);
功能:
将流的偏移量重定位到开头
//从终端输入一个文件的路径,打印该文件的大小
#include
int main(void)
{
char rode[32] = {0};
FILE *fp = NULL;
long len = 0;
printf("please put rode:
");
gets(rode);
fp = fopen(rode, "r");
if(NULL == fp)
{
perror("fail to fopen");
return -1;
}
fseek(fp, 0, SEEK_END);
len = ftell(fp);
printf("size:%ld
" ,len);
fclose(fp);
return 0;
}
14. feof
int feof(FILE *stream);
功能:
判断流是否到达末尾
15. ferror
int ferror(FILE *stream);
功能:
判断流是否出错
如果出错可以使用clearerror清除错










