标准I/O及缓冲区

Linux下一切皆文件
全缓冲:当流的缓冲区无数据或无空间时才执行实际的 I/O 操作
行缓冲:当输入和输出中遇到换行符(’ \n ‘)时,进行I/O 操作,当流和一个终端关联时,典型的行缓冲
无缓冲:数据直接写入文件,流不进行缓冲

标准I/O预定义的3个流,程序运行时自动打开

流名称 描述符值 描述符 结构体名称
标准输入流 0 STDIN_FILENO stdin(默认行缓冲)
标准输出流 1 STDOUT_FILENO stdout(默认行缓冲)
标准错误流 2 STDERR_FILENO stderr

缓冲区的大小为1kb,即1024个字节

文件的打开和关闭

1
FILE *fopen(const char *path, const char *mode);
  • path为文件路径
  • mode为打开方式
  • 成功时发回FILE类型流指针,失败时返回NULL
模式参数 说明
“r” 或 “rb” 以只读的方式打开文件或二进制文件,文件必须存在
“r+” 或 “r+b” 以读写的方式打开文件或二进制文件,文件必须存在
“w” 或 “wb” 以只写的方式打开文件或二进制文件,文件存在时会清空文件内容,文件不存在则创建
“w+” 或 “w+b” 以读写的方式打开文件或二进制文件,文件存在时会清空文件内容,文件不存在则创建
“a” 或 “ab” 以只写的方式打开文件,文件存在数据写入文件末尾,文件不存在则创建
“a+” 或 “a+b” 以读写的方式打开文件,文件存在数据写入文件末尾,文件不存在则创建

处理错误信息

1
2
void perror(const char *s);
char strerror(int errno); // 在string.h头文件中被定义
  • errno:存放错误号,由系统生成
  • perror:先输入字符串s,再输出错误号对应的错误信息
  • strerror:根据错误号返回对应的错误信息

文件的关闭

1
int fclose(FILE *stream);
  • fclose()调用成功返回0,失败返回EOF,并设置errno
  • 流关闭时自动刷新缓冲中的数据并释放缓冲区
  • 当一个程序正常终止时,所有打开的流都会被关闭
  • 流一旦关闭后就不能执行任何操作

读写流函数

函数 参数说明
int fgetc(FILE *stream) stream:文件流类型指针
返回值:成功时返回所读字符,遇到文件末尾或出错返回EOF(-1)
int getc(FILE *stream) stream:文件流类型指针
返回值:成功时返回所读字符,遇到文件末尾或出错返回EOF(-1)
char *fgets(FILE *stream) stream:文件流类型指针
返回值:成功时返回所读字符串,遇到文件末尾或出错返回EOF(-1)
int fputc(char ch, FILE *stream) ch:要往文件写入的字符串
stream:文件流类型指针
返回值:写入成功时返回写入字符,出错时返回EOF(-1)
int fputs(const char *s, FILE *stream) ch:要往文件写入的字符串
stream:文件流类型指针
返回值:写入成功时返回一个非负的正整数,出错时返回EOF(-1)
  • getchar() 等同于 fgetc(stdin) ,两者的区别是一个是宏一个是函数。
  • putchar(c) 等同于fputc(c, stdout)

按对象来读写

既可以读文本文件,也可以读二进制文件,效率高

1
2
size_t fread(void *ptr, size_t size, size_t n, FILE *fp);
size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);
  • 返回值:成功返回读写的对象个数,出错时返回EOF(-1)
  • ptr:读取的数据存放指针(fread),写入的数据存放的指针(fwrite)
  • size:读或写入数据块的大小
  • n:读或写入数据块的个数
  • fp:要读取或写入的文件指针

注意:在写入数据后文件指针会指向写入数据的末尾,若要读取内容需要先关闭再打开、或者使用刷新指针指向。

文件流刷新定位函数

1
int fflush(FILE *fp);
  • 返回值:成功返回0,失败返回EOF
  • 将流缓冲区中的数据写入实际的文件
  • Linux下只能刷新输出缓冲区,输入缓冲区丢弃
    输出到屏幕使用stdout流

定位流函数

1
2
3
long ftell(FILE *stream);
long fseek(FILE *stream, long offset, int whence);
void rewind(FILE *stream);
  • ftell:函数成功时返回当前的读写位置,错误时返回EOF

  • fseek:定位一个流,成功时返回0,错误返回EOF,

    • offset参数:偏移量,不能大于2G
    • whence参数:SEEK_SET(文件开头偏移)、SEEK_CUR(以当前位置往后增加)、SEEK_END(文件尾增加偏移量)
  • rewind:使文件流指针返回文件开头位置进行读写

  • 使用a模式打开文件时,fseek函数无效

格式化输入输出函数

1
2
int fscanf(FILE *stream, const char *fmt, ...);	// 从文件内容按格式取值到变量中
int sscanf(char *s, const char *fmt, ...); // 从字符串按格式取值到变量中
1
2
int sprintf(char *s, const char *fmt, ...);		// 格式化写入到缓冲区
int fprintf(FILE *stream, const char *fmt, ...); // 格式化写入到文件中
  • 成功时返回输出的字符个数,出错时返回EOF