目录
按字符 fgetc(3) getchar(3) getc(3)
按行 gets(不推荐) fgets(3) getline(3)
按字符 fputc(3) putchar(3) putc(3)
1.0 文件流
文件流是已打开文件的标志,是一个结构体类型的指针,FILE *
1.1 打开流
fopen(3)
FILE *fopen(const char *pathname, const char *mode)
> 如果有创建,则文件的权限给的是0666,但是进程是有文件umask(默认0002)
文件真正的权限是mode & ~umask
> FILE * 返回值类型
> pathname 文件地址
> mode 打开方式
## 六种模式
"r" 只读,文件流在开头(文件流决定操作文件的位置)
"r+" 读写,文件流在开头
"w" 只写,文件不存在则创建,存在则截断为0
"w+" 读写,文件不存在创建,存在则截断为0
"a" 追加,末尾写,文件不存在创建
"a+" 开头读末尾写,文件不存在创建
fopen(3) 返回值
- 成功返回FILE*也就是文件流
- 失败返回NULL
1.2读
按字符 fgetc(3) getchar(3) getc(3)
int fgetc(FILE *stream);
fgetc(3)返回值
- 成功返回读到的字符
- 失败返回EOF度出错也返回EOF EOF为-1
int ferror(FILE *fp)检测是否读出错
int feof(FILE *fp) 检测是否到文件的末尾
按行 gets(不推荐) fgets(3) getline(3)
char *fgets(char *s, int size, FILE *stream);
1. 从stream中最多读取size-1个字符到地址空间 最后为'\0'
2. 遇到'\n'或者EOF就不读了
3. 读完出错都返回NULL
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
1. 从stream读取一整行到lineptr 存储空间为*n
2. *lineptr如果是NULL, 并*n为0,则getline开辟*n大小的存储空间,起始地址是*lineptr
3. *lineptr本身就有动态开辟的存储空间,*n个字节大小,那么当不足以容纳一行,则getline会再开辟
4. 返回读到的字符个数
5. 调用者手动释放
结构fread(3)
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
1. 从stream中读nmemb成员,每个成员size字节大小,到ptr中
2. 返回读到的成员个数
3. 读到文件结束标志返回0
1.3写
按字符 fputc(3) putchar(3) putc(3)
int fputc(int c, FILE *stream);
1. 将字符c写入stream文件
按行 puts(3) fputs(3)
int fputs(const char *s, FILE *stream);
int puts(const char *s);
结构 fwrite(3)
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
1. 将ptr中nmemb个成员,每个成员size个字节,写到stream中
2. 返回值是写入的成员个数
1.4定位
fseek(3)
int fseek(FILE *stream, long offset, int whence);
1. 文件stream相对whence偏移offset个字节
2. whence:SEEK_SET 开头 SEEK_CUR当前 SEEK_END末尾
rewind(3)
等效果与fseek(stream, 0L, SEEK_SET);
ftell(3)
获取文件偏移量
1.5关闭
fclose(3)
拓展
缓存区
标准io是有缓存的
用途
缓存区是为了提高程序的效率,降低成本(类似于驿站)
减少系统调用
分类
-
行缓存
- 遇到’\n’缓存区就会刷新了(例如stdout stdin)
- 进程正常终止
- 强制刷新fflush(3)
- 缓存区满了
-
全缓存
- 进程正常终止
- 强制刷新fflush(3)
- 缓存区满了(默认4k)
-
无缓存
stderr