目录
1、打开或者新建文件(fopen) / 关闭文件(fclose)
3、按对象读写 —— fread( ) / fwrite( )
标准IO
1、概念
标准IO遵循ANSI C标准(C99 C11)调用标准C库的头文件
标准IO的实现实际上是通过调用标准C库中的函数完成
2、特点
标准IO利用缓冲机制、减少系统调用的次数、从而提高程序的运行效率
3、流——stream
数据简单地从文件流入或者流出,这种现象就称为流
在程序中流一般使用 "FILE"结构体来表示流,一个文件对应一个流(FILE结构体)
4、流的类型
文本流:
"1234"-> '1' '2' '3' '4' ->0000 0001 0000 0010 0000 0011 0000 0100
二进制流:
"1234"-> '1234' ->0100 1101 0010
换行符:
文本流换行符: '\r''\n'
二进制流换行符: '\n'
//注意: linux操作系统下,不区分文本流和二进制流,全部都当成二进制流处理
5、特殊流
当用户打开一个文件时,系统会默认打开3个特殊流:标准输入流、标准输出流、标准错误流
标准输入流 ——> 0 ——> stdin
标准输出流 ——> 1 ——> stdout
标准错误流 ——> 2 ——> stderr
6、缓冲区类型
全缓冲区
当用户打开一个文件时,默认使用全缓存。当缓冲区满时,才会进行实际的IO操作
行缓冲区
当IO操作跟终端相关时,使用行缓存。当缓冲区满或者遇到'\n'时,才会进行实际的IO操作
无缓冲区
进行错误输出打印时,使用无缓存
标准IO相关的库函数
1、打开或者新建文件(fopen) / 关闭文件(fclose)
(1)打开或者新建文件(fopen)
#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
参数:
pathname:文件名(包含路径)
mode:文件打开方式
r -- 以只读方式打开文件,文件必须要存在
r+ -- 以读写方式打开文件,文件必须要存在
w -- 以只写方式打开文件,打开文件后会先将文件内容清空,如果文件不存在,则创建文件
w+ -- 以读写方式打开文件,打开文件后会先将文件内容清空,如果文件不存在,则创建文件
a -- 以追加的方式打开文件,所有对文件的写操作都在文件末尾进行,如果文件不存在,则创建文件
a+ -- 以读写的方式打开文件,所有对文件的写操作都在文件末尾进行,如果文件不存在,则创建文件//注意:方式默认为文本流打开,需要二进制流打开如下:
rb -- 以只读方式打开文件,文件必须要存在
r+b -- 以读写方式打开文件,文件必须要存在
wb-- 以只写方式打开文件,打开文件后会先将文件内容清空,如果文件不存在,则创建文件
w+b -- 以读写方式打开文件,打开文件后会先将文件内容清空,如果文件不存在,则创建文件
ab -- 以追加的方式打开文件,所有对文件的写操作都在文件末尾进行,如果文件不存在,则创建文件
a+b -- 以读写的方式打开文件,所有对文件的写操作都在文件末尾进行,如果文件不存在,则创建文件返回值:
成功返回流指针,失败返回NULL;
eg:
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt","r");
if(NULL == fp)
{
perror("fopen");
return -1;
}
printf("成功打开\n");
return 0;
}
ie:
(2)关闭文件(fclose)
#include <stdio.h>
int fclose(FILE *stream);
参数:
stream:对应文件的流指针
eg:
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt","r");
if(NULL == fp)
{
perror("fopen");
return -1;
}
printf("成功打开\n");
fclose(fp);//关闭文件
return 0;
}
ie:
2、读写文件
1、按字节读写 ——fgatc( ) / fputc( )
(1)按字节读fgatc( )
#include <stdio.h>
int fgetc(FILE *stream);
参数:
stearm:文件对应的流指针
返回值:
成功返回得到的字符,失败或者读到文件末尾返回EOF(-1)
eg:
#include <stdio.h>
int main(int argc, char *argv[])
{
//打开文件
FILE *fp = fopen("1.txt","r");
if(NULL == fp)
{
perror("fopen");
return -1;
}
//读取单个字符
char ch = fgetc(fp);
printf("ch = %c\n",ch);
fclose(fp);//关闭文件
return 0;
}
ie:
(2)按字节写 fputc( )
#include <stdio.h>
int fputc(int c, FILE *stream);
参数:
c:输出的字符
stream:文件对应的流指针返回值:
成功返回输出的字符,失败返回EOF(-1);
eg:
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt","a");
if(NULL == fp)
{
perror("fopen");
return -1;
}
printf("成功打开\n");
//写入一个字符到文件中
char ch = 'n';
fputc(ch,fp);
fclose(fp);//关闭文件
return 0;
}
ie:
2、按行读写 —— fgets( ) / fputs( )
(1)按行读fgets( )
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
参数:
s:用于存储读取的首地址
size:指定读取的最大字节数
stream:文件对应的流指针
返回值:
成功返回读取一行的数据,失败或者读到文件末尾返回NUL
特点:
如果读取的字数达不到最大字节数时fgets会以'\n'/结束
当遇到'\n'(换行符)时,fgets读取结束
如果读取的字数超过最大字节数时最大读取少一个
fgets一次最多读取size-1个字节因为字符最后一个是'\0'
eg:
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt","r");
if(NULL == fp)
{
perror("fopen");
return -1;
}
char ch[32] = {0};
fgets(ch,32,fp);
printf("%s",ch);
fclose(fp);//关闭文件
return 0;
}
ie:
(2)按行写fputs( )
#include <stdio.h>
int fputs(const char *s, FILE *stream);
参数:
s:输入内容的首地址
stream:流指针
返回值:
成功返回一个非负值,失败返回-1
eg
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt","a");
if(NULL == fp)
{
perror("fopen");
return -1;
}
//写入一行字符到文件中
char ch[54] = {"hello world"};
fputs(ch,fp);
fclose(fp);//关闭文件
return 0;
}
ie
3、按对象读写 —— fread( ) / fwrite( )
(1)按对象读fread( )
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
参数:
ptr:用于存储读取内容的首地址
size:对象大小
nmemb:对象个数
stream:流指针返回值:
成功返回读取的对象个数,失败返回比指定对象个数小的一个值或者0
eg
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt","a+");
if(NULL == fp)
{
perror("fopen");
return -1;
}
char ch[64] = {0};
int ret = fread(ch, sizeof(int), 3, fp);
printf("ret = %d,arr = %s \n",ret,ch);
fclose(fp);//关闭文件
return 0;
}
ie
(2)按对象写fwrite( )
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
参数:
ptr:用于存储读取内容的首地址
size:对象大小
nmemb:对象个数
stream:流指针返回值:
成功返回写入的对象个数,失败返回比指定对象个数小的一个值或者0
eg
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt","a+");
if(NULL == fp)
{
perror("fopen");
return -1;
}
char ch[64] = {"adswqwertyioasdkv"};
int ret = fwrite(ch,sizeof(int), 4,fp);
fclose(fp);//关闭文件
return 0;
}
ie
3、文件定位 -- tell、fseek、rewind
(1)文件定位 -- tell
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
参数:
stream:流指针
offset:偏移量,可正可负,正表示向后偏移,负表达向前偏移
whence:基准点
SEEK_SET:文件开头
SEEK_CUR:文件指针当前位置
SEEK_END:文件末尾
返回值:
成功返回0,失败返回-1
eg
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt","r");
if(NULL == fp)
{
perror("fopen");
return -1;
}
fseek(fp,6,SEEK_SET);
char ch = fgetc(fp);
printf("ch = %c\n",ch);
fclose(fp);//关闭文件
return 0;
}
ie
(2)文件定位 -- fseek(查看目前文件所在的位置)
#include <stdio.h>
long ftell(FILE *stream);
参数:
stream:流指针
返回值:
成功返回文件指针当前位置相对于文件开头的偏移量,失败返回-1
eg
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt","r");
if(NULL == fp)
{
perror("fopen");
return -1;
}
fseek(fp,6,SEEK_SET);
char ch = fgetc(fp);
printf("ch = %c\n",ch);
//回到文件开头
rewind(fp);
ch = fgetc(fp);
printf("ch = %c\n",ch);
//去文件的末尾
fseek(fp,0,SEEK_END);
int size = ftell(fp);
printf("文件大小:%d\n",size);
fclose(fp);//关闭文件
return 0;
}
ie
(3)文件定位 -- rewind
#include <stdio.h>
void rewind(FILE *stream);
功能:
将文件指针定位在文件开头
参数:
stream:流指针
eg
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt","r");
if(NULL == fp)
{
perror("fopen");
return -1;
}
fseek(fp,6,SEEK_SET);
char ch = fgetc(fp);
printf("ch = %c\n",ch);
//回到文件开头
rewind(fp);
ch = fgetc(fp);
printf("ch = %c\n",ch);
fclose(fp);//关闭文件
return 0;
}
ie
4、刷新流 -- fflush
(1)刷新流 -- fflush
#include <stdio.h>
int fflush(FILE *stream)
参数:
stream:流指针
返回值:
成功返回0,失败返回-1
eg
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("hello");//行缓存没有遇到‘\n’无法进行IO操作
fflush(stdout);
while(1);
return 0;
}
ie