引言
标准IO是ANSIC建立的一个标准IO模型,不依赖于系统内核。只要开发环境中有标准IO库,标准IO就可以使用。
linux中使用的是glibc,它是标准C库的超集。不仅包含ANSIC中定义的函数,还包括POSIX标准中定义的函数。因此,linux下既可以使用标准IO又可以使用文件IO。
流和FILE结构体
文件IO函数都是围绕着文件描述符来进行的。而标准IO是围绕流(stream)进行的。
FILE结构体,包含了标准IO库为管理该流需要的所有信息。
标准输入、标准输出和标准错误
对一个进程预定义的3个流,通过预定义文件指针stdin、stdout和stderr加以引用。这3个文件指针定义在头文件<stdio.h>中。
这些流引用的文件与文件IO中提到的文件描述符STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO所引用的相同。
缓冲
标准IO提供了3种类型的缓冲:
(1) 全缓冲。在填满标准IO缓冲区后才进行实际IO操作。
(2) 行缓冲。当在输入和输出中遇到换行符时才执行IO操作。
(3) 不带缓冲。
更改缓冲类型:
#include <stdio.h>
void setbuf(FILE *restrict fp, char *restrict buf);
int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);
打开和关闭
打开:
声明:
#include <stdio.h>
FILE *fopen(const char *restrict pathname, const char *restrict type);
参数:
pathname:文件路径名
type:以什么方式打开文件
r/rb:读文本文件/读二进制文件
w/wb:写
a/ab:追加
r+/r+b/rb+:打开文件,读或写
w+/w+b/wb+: 创建文件,读或写
a+/a+b/ab+:打开或创建文件,以追加方式读或写
返回值:
success: FILE指针
fail: NULL
关闭:
#include <stdio.h>
int fclose(FILE *fp);
读和写
一次读、写一个字节
输入函数:
声明:
#include <stdio.h>
int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void); //读取stdin中的一个字符
返回值:
success: 读到的字符,
fail: 出错或到达文件尾端,均返回EOF
为了判断是出错还是到达文件尾端,使用如下函数判断
#include <stdio.h>
int ferror(FILE *fp);
int feof(FILE *fp);
例:
char c;
FILE *fp;
fp = fopen(FILE_PATH, w);
c = fgetc(fp);
if(c == EOF)
{
if(ferror(fp))
printf("读取文件出错\n");
else
printf("到达文件尾端\n");
}
else
printf("读取的字符为:%c\n", c);
//-------------------------------------------------
输出函数:
声明:
#include <stdio.h>
int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c); //将字符输出至stdout
返回值:
success: c
fail: EOF
每次读写一行数据
输入函数:
声明:
#include <stdio.h>
char *fgets(char *restrict buf, int n, FILE *restrict fp)
char *gets(char *buf); //从标准输入读取一行
返回值:
fail: 已达到文件尾端或出错,返回NULL
输出函数:
声明:
#include <stdio.h>
int fputs(const char *restrict str, FILE *restrict fp);
int puts(const char *str); //向标准输出写入一行
返回值:
success: 非负
fail:EOF
一次读写一个完整的结构
声明:
#include <stdio.h>
size_t fread(void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);
size_t fwrite(const void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);
参数:
ptr:待读入/写入成员的起始地址。该地址必须包括size*nobj的空间
size:单位成员所占字节数
nobj:成员个数
fp: FILE指针
返回值:
success:读或写的对象数
fail:返回值少于nobj。
读情况:调用ferror或feof来判断是到达尾端还是出错。
写情况:出错
例:
//将浮点数数组的2-5元素写入文件
float data[10];
if(fread(&data[2], sizeof(float), 4, fp) != 4)
//写入一个结构体
struct {
short count;
long total;
char name[NAMESIZE];
}item;
if(write(&item, sizeof(item), 1, fp) != 1)
文件定位
声明:
#include <stdio.h>
int fseek(FILE *fp, long offset, int whence);
参数:
fp: FILE指针
offset:偏移量
whence:偏移的起始位置
SEEK_CUR: 当前文件位置
SEEK_SET:文件起始位置
SEEK_END:文件尾端位置
格式化输入输出
- 格式化输出
声明:
#include <stdio.h>
int printf(const char *restrict format, ...);//输出至标准输出
int fprintf(FILE *restrict fp, const *restrict format, ...);//写至指定的流
int snprintf(char *restrict buf, size_t n, const char *restrict format, ...)//以指定格式写入数组中
- 格式化输入
声明:
#include <stdio.h>
int scanf(const char *restrict format, ...);
int fscanf(FILE *restrict fp, const char *restrict format, ...);
int sscanf(const char *restrict buf, const char *restrict format, ...);