标准IO
标准IO是由标准C库所提供的函数接口,接口功能丰富,有提供缓冲区,因此对于处理海量数据时效率比较高,所以编程过程中应该尽可能的使用标准IO,而非系统IO。
标准IO接口
fopen (打开文件)
头文件:
#include <stdio.h>
定义函数:
FILE * fopen(const char * path, const char * mode);
参数分析:
path --> 需要打开的文件的路径
mode --> 打开文件的模式
. r 打开 只读 文件, 该文件必须存在.
. r+ 打开可 读写 的文件, 该文件必须存在.
. w 打开 只写 文件,若文件存在则文件长度清为 0, 即该文件内容会消失. 若文件不存在则建立该文件.
. w+ 打开可 读写 文件,若文件存在则文件长度清为零, 即该文件内容会消失. 若文件不存在则建立该文件.
. a 以附加的方式打开 只写 文件,若文件不存在, 则会建立该文件, 如果文件存在, 写入的数据会被加到文件尾, 即文件原先的内容会被保留.
. a+ 以附加方式打开可 读写 的文件,若文件不存在, 则会建立该文件, 如果文件存在, 写入的数据会被加到文件尾后, 即文件原先的内容会被保留.
返回值:
成功 返回指向该文件的流指针 (类似OPEN的返回))
失败 返回NULL
fwrite (将数据写至文件流)
头文件:
#include <stdio.h>
定义函数:
size_t fwrite(const void * ptr, size_t size,
size_t nmemb, FILE * stream);
参数分析:
ptr --> 需要写入数据所在的地址
ptr --> 每一块数据的大小
nmemb --> 需要写入多少块
stream --> 需要写入到哪个文件流中
返回值:
返回实际写入的 nmemb 数目
fread (从文件流读取数据)
头文件:
#include <stdio.h>
定义函数:
size_t fread(void * ptr, size_t size,
size_t nmemb, FILE * stream);
参数分析:
ptr --> 需要读取的数据放到哪里(用户缓冲区)
ptr --> 每一块数据的大小
nmemb --> 需要写入多少块
stream --> 需要读取的哪个文件流
返回值:
返回实际读取到的 nmemb 数目.
fseek (移动文件流的读写位置)
头文件:
#include <stdio.h>
定义函数:
int fseek(FILE * stream, long offset, int whence);
参数分析:
stream --> 文件流指针
offset --> 偏移量
whence --> 偏移方式
SEEK_SET 从距文件开头 offset 位移量为新的读写位置.
SEEK_CUR 以目前的读写位置往后增加offset 个位移量.
SEEK_END 将读写位置指向文件尾后再增加 offset 个位移量. 当 whence 值为 SEEK_CUR 或SEEK_END 时, 参数 offset 允许负值的出现.
返回值:
当调用成功时则返回 0,
若有错误则返回-1, errno 会存放错误代码.
feof (检查文件流是否读到了文件尾)
头文件:
#include <stdio.h>
定义函数:
int feof(FILE * stream);
参数分析:
stream --> 需要检查的文件流指针
返回值:
返回非零值代表已到达文件尾 (0 表示不是文件末尾,也就是出现异常情况)
ferror (检查文件流是否有错误发生)
头文件:
#include <stdio.h>
定义函数:
int ferror(FILE *stream);
参数分析:
stream --> 需要检查的文件流指针
返回值:
如果文件流有错误发生则返回非 0 值 (0表示没有错误)
fgets ( 由文件中读取一字符串)
头文件:
include<stdio.h>
定义函数:
char * fgets(char * s, int size, FILE * stream);
参数分析:
s --> 读取到的数据所存放的用户缓冲区
size --> 期望读取的字节数
stream --> 需要读取的文件的流指针
返回值:
若成功则返回 s 指针
返回 NULL 则表示有错误发生
注意:
1.出现换行字符、读到文件尾才停止读取;
2.最后会加上NULL作为字符串结束,所以需要预留一个字节。
fputs ( 将一指定的字符串写入文件内)
头文件:
#include <stdio.h>
定义函数:
int fputs(const char * s, FILE * stream);
参数分析:
s --> 需要写入的内容的地址
stream --> 输出到哪个文件中
返回值:
若成功则返回写出的字符个数,
返回 EOF 则表示有错误发生.
错误码errno
需要添加头文件 errno.h,其实本质上是一个全局变量默认值为,所有的库函数、系统函数出错时都会自觉的去修改该变量处理错误号码的函数有两个。
// 直接输出出错的信息 , s 可由用户输出出错提示
void perror(const char *s);
// 返回错误原因的字符串指针 , errnum 对应的错误号码
char *strerror(int errnum);
注意:
1.读取fread(), 既可以处理二进制, 也可以处理文本;
2.fgets()只能处理文本信息;
3.fgetc()只能处理文本信息;
4.scanf()从标准输入中读取信息;
5.fscanf()从指定的文件中读取信息;
6.写fwrite(), 既可以处理二进制,也可以处理文本。
测试代码
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define read_size 30
int main(int argc, char const *argv[])
{
FILE *file;
char *filename = "./file";
file = fopen(filename, "w+");
if (NULL == file)
{
printf("Open %s error, msg:%s
", filename, strerror(errno));
return -1;
}
char f_write[] = "fwrite
";
int ret = fwrite(f_write, sizeof(f_write), 1, file);
printf("%d
", ret);
char f_putc[] = "fputc
";
for (int i = 0; i < strlen(f_putc); i++)
{
char ret = fputc(f_putc[i], file);
if (EOF == ret)
{
printf("fputc error
");
return -1;
}
}
char *f_puts = "fputs
";
ret = fputs(f_puts, file); //?
if (EOF == ret)
{
printf("fputs error
");
return -1;
}
printf("The return value of fputs is %d
", ret); //返回非负值
fseek(file, SEEK_SET, 0);
char read[read_size];
ret = fread(read, sizeof(char), read_size, file);
if (ret < read_size)
{
if (!feof(file))
{
if (ferror(file))
{
perror("write error ");
return -1;
}
}
}
printf("Read file :%s", read);
printf("Read file len:%d
", ret);
fseek(file, SEEK_SET, 0);
char f_gets[read_size];
char *har = fgets(f_gets, read_size, file); //读到换行字符结束
if (NULL == har)
{
printf("fgets %s error, msg:%s
", filename, strerror(errno));
return -1;
}
printf("f_gets file :%s", f_gets);
fclose(file);
return 0;
}