标准IO
#include <stdio.h>
//stdio:标准的输入输出 标准IO
printf/scanf//就是标准IO的接口
文件IO和标准IO
文件IO:是系统调用
标准IO:是库函数
系统调用和库函数
- 系统调用
- 从用户空间进入内核空间的一次过程就是一次系统调用
- 系统调用没有缓冲区,效率比较低。系统调用的可移植性比较差
- 库函数
- 库函数 = 缓冲区 + 系统调用
- 效率比系统调用的高,可移植性高
标准IO和文件IO的常用接口
- 文件IO:
open read write close ...
- 标准IO:
printf scanf fopen fread fwrite fclose
标准IO
-
FILE指针
-
FILE是一个结构体,fopen函数的返回值是FILE的指针,这个FILE指针记录了打开文件的所有的信息以后在操作文件的时候就通过FILE完成
-
typedef struct _IO_FILE FILE;
-
struct _IO_FILE { char* _IO_buf_base; //缓冲区的起始地址 char* _IO_buf_end; //缓冲区的结束地址 ... }
-
在一个正在运行的程序中默认已经产生了三个FILE指针
- stdin:标准输入
- stdout:标准输出
- stderr:标准出错
-
标准IO常用函数
fopen函数
-
#include <stdio.h> FILE *fopen(const char *pathname, const char *mode);
-
功能:使用标准IO接口打开文件,在用户空间申请一片缓冲区
-
参数:
-
文件的路径和名字
-
打开文件的方式
-
参数 功能 r 只读方式打开文件,光标定位到文件开头 r+ 以读写方式打开文件,光标定位到文件开头 w 有则清空,无则创建,以只写的方式打开文件,光标定位到文件开头 w+ 有则清空,无则创建,以读写的方式打开文件,光标定位到文件开头 a 无则创建,以追加的方式打开文件,光标定位到文件末尾 a+ 无则创建,以读和追加的方式打开文件,读则开头,尾则结尾 -
返回值
- 成功:返回FILE*类型
- 失败:返回NULL,更新errno(错误码)
- 不同的错误,errno不同
-
-
perrop
-
功能:根据errno打印对应的错误信息
-
原型:
-
#include <stdio.h> void perror(const char *s);
-
-
参数:
char *s
用于提示的字符串- 例如:函数名 error:
strerror
-
功能:将给定的错误码,变成对应的字符串信息
-
原型
-
#include <string.h> char *strerror(int errnum);
-
-
参数:错误码
-
返回值
- 成功:指定错误码信息
- 失败:Unknown error nnn
errno错误码头文件
#include <errno.h>
用fread和fwrite实现,要求拷贝一个文件,例如将1.c中的内容拷贝到2.c中
int copy_file(FILE *fp_r, FILE *fp_w)
{
//读一次,写一次
char buf[32] = "";
size_t res = 0;
while(1)
{
//以一个字节为单位读取数据,每次读取sizeof(buf)个
//最后一次会小于sizeof(buf)
if(res = fread(buf, 1, sizeof(buf), fp_r), fp_r == 0)
break;
//写入数据,以1字节为单位,写入实际读取到的数据,res 个
fwrite(buf, 1, res, fp_w);
}
puts("copy complete");
return 0;
}
用fgets和fputs实现,拷贝一个文件,并计算文件的行数和大小
void copy_fgets(FILE* f_r, FILE* f_w)
{
char buf[32] = "";
long size = 0;
int line = 0;
while(fgets(buf, sizeof(buf), f_r) != NULL)
{
if(buf[strlen(buf)-1] == '\n')
{
line++;
}
fputs(buf, f_w);
size+=strlen(buf);
}
printf("拷贝的文件行数为%d\n", line);
printf("拷贝的文件大小为%ld字节\n", size);
}