一、标准IO
1.概念:
定义在C库中的一组可以输入输出的函数
2.特点:
- 有缓存区
- 围绕流 FILE *进行操作
- 默认打开三个,标准输入——stdin 标准输出——stdout 标准错误——stderr
3.缓存区:
行缓存 全缓存 不缓存
3.1刷新缓存的条件:
- 程序正常退出
- \n刷新
- 缓存区满
- fflush强制刷新
3.2全缓存:和文件操作有关
3.3不缓存:标准错误stderr
二、函数
2.1打开文件 fopen
FILE * fopen ( const char * path , const char * mode );功能:打开文件参数:
path:打开文件
mode:打开方式
r:只读,流被定位到文件开头
r+:可读可写,流被定位到文件开头
w:只写,文件不存在创建,文件存在清空,流被定位到文件开头
w+:可读可写,文件不存在创建,文件存在清空,流被定位到文件开头
a:追加,文件不存在创建,存在追加,流被定位到文件末尾
a+:可读可写,文件不存在创建,存在追加,开始进行读时从头读,进行写时流被定位到文件末尾
返回值:
成功:文件流
失败:NULL,并且设置errno(错误码)
示例:
#include <stdio.h>
int main()
{
FILE *fp = fopen("./1.txt","r");
if(fp == NULL)
{
perror("fopen err");
return -1;
}
}
2.2关闭文件 fclose
int fclose(FILE* stream);
功能:关闭文件
参数:stream:文件流
2.3读文件 fgetc
int fgetc ( FILE * stream );功能:从文件中读一个字符
参数:stream:文件流
返回值:
成功:读到字符
失败或读到文件末尾:EOF(-1)
示例:
练习:实现cat命令
cat 文件名
思路:打开文件,循环读文件,当读到文件末尾时循环结束,打印读到数据,关闭文件
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *fp = fopen("1.txt", "r");
if (fp == NULL)
{
perror("fopen err");
return -1;
}
char ch;
while ((ch = fgetc(fp)) != EOF)
{
printf("%c",ch);
}
fclose(fp);
return 0;
}
补充 ferror feof
int ferror(FILE* stream)
功能:判断读文件时是否出错
返回值:非0表示错
int feof(FILE* stream)
功能:读文件时是否读到文件末尾
返回值:非0表示读到文件末尾
示例:
2.4写文件 fputc
int fputc ( int c , FILE * stream )功能:向文件中写入一个字符
参数:c:要写的字符
stream:文件流
返回值:成功:写的字符的ASCII
失败:EOF
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *fp = fopen("./1.txt", "w+");
if (fp == NULL)
{
perror("fopen err");
return -1;
}
fputc('a', fp);
fputc(65, fp);
int ch = fgetc(fp);
printf("%c", ch);
fclose(fp);
return 0;
}
2.5每次一串字符的读写 fgets
char * fgets ( char * s , int size , FILE * stream );功能:从文件中读取一串字符
参数:
s:存放读取的字符串的首地址
size:读取的大小
stream:文件流
返回值:
成功:读取的字符串的首地址
失败或读到文件末尾:NULL
特性:
1.一次调用最多读取一行数据
2.实际读到个数为size-1个,末尾自动添加\0
练习:实现wc-l命令
wc -l 文件名:显示文件的行数思路:打开文件,循环读文件,当读到文件末尾时循环结束,在循环中判断是否是一行,如果是则对整型变量进行自加,关闭文件。
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *fp = fopen("./1.c", "r");
if (fp == NULL)
{
perror("fopen err");
return -1;
}
printf("fopen success\n");
int res = 0;
char buf[1024] = "";
char *p = fgets(buf, 1024, fp);
while (p != NULL)
{
res++;
p = fgets(buf, 1024, fp);
}
printf("%d\n", res);
fclose(fp);
return 0;
}
2.6写字符串 fputs
int fputs(const char *s, FILE *stream);
功能:向文件中写字符串
参数:s:要写的内容
stream:文件流
返回值:成功:非负整数
失败:EOF
示例:
2.7二进制读写文件
可以读写任意类型的数据,以二进制方式进行读写
2.7.1fread
size_t fread ( void * ptr , size_t size , size_t nmemb , FILE * stream );功能:从文件流读取多个元素
参数:
ptr :用来存放读取元素 (可以用来读取任意类型的数据)
size :元素大小 sizeof(数据类型)
nmemb :读取对象的个数
stream :要读取的文件
返回值:
成功:读取对象的个数
读到文件尾或失败:0
2.7.2fwrite
size_t fwrite ( const void * ptr , size_t size , size_t nmemb , FILE * stream );功能:按对象写
参数:同上
返回值:
成功:写的元素个数
失败 :0
示例:
2.8文件定位操作
2.8.1rewind
void rewind ( FILE * stream );功能:将文件位置指针定位到起始位置
2.8.2fseek
int fseek ( FILE * stream , long offset , int whence );功能:文件的定位操作
参数:
stream:文件流
offset:偏移量:正数表示向后文件尾部偏移,负数表示向文件开头偏移
whence:相对位置:
SEEK_SET:相对于文件开头
SEEK_CUR:相对于文件当前位置
SEEK_END:相对于文件末尾
返回值:
成功:0
失败:-1
示例:
2.8.3ftell
long ftell ( FILE * stream );功能:获取位置指针当前的文件位置
参数:要检测的文件流
返回值:成功:当前的文件位置,出错:-1
示例:
补充:
- rewind(fp)和fseek(fp, 0, SEEK_SET)等价
- 可以通过此函数计算文件中字符个数
- 当打开文件的方式为a或a+时,fseek不起作用
重定向打开文件
FILE * freopen ( const char * pathname , const char * mode , FILE * fp )功能:将指定的文件流重定向到打开的文件中
参数:path:文件路径
mode:打开文件的方式(同fopen)
fp:文件流指针
返回值:成功:返回文件流指针
失败:NULL
示例: