目录
一,打开与关闭文件
1.打开文件:
(1).fopen
(2).freopen
2.关闭文件:
二,读写文件
1.一个字符的读和写
(1).读fgetc:
(2).写fputc:
2.每次一行的读写
(1).读fgets
(2).写fputs
3.任意长度读写
(1).读fread
(2).写fwrite
三,文件内的定位操作
(1).rewind定位开头
(2).fseek任意定位
FILE *fopen(const char *path,const char *mode);
①功能:打开文件
②参数:
path:打开的文件,一般是"./可执行文件";或者使用argv[1],然后在./a.out后空格输入文件名
mode:打开的方式(双引号括起),共六种;
r:只读,文件不存在时报错,文件流 定位到文件开头;
r+:可读可写,文件不存在时报错,文件流 定位到文件开头;
w:只写,文件不存在时创建,文件存在时清空原文件内容;
w+:可读可写,文件不存在时创建,文件存在时清空原文件内容;
a:在文件末尾追加,文件不存在时创建,存在时追加内容,文件流定位到文件末尾;
a+:读和追加,文件不存在时创建,存在时追加内容,文件流定位到文件末尾;
当以a的方式打开文件时,只能在文件末尾追加写,定位操作不能更改追加的位置,但是可以改变读的位置。
③返回值:成功->文件流;
失败->NULL,并设置错误码。
#include
int main(int argc, char const *argv[])
{
FILE *fp;
fp = fopen("./test.c","w");
if(NULL == fp)
{
printf("fopen error\n");
//或使用perror函数,直接输出错误信息
perror("fopen error");
return -1
}
printf("fopen success\n");
return 0;
}
FILE * freopen(const char *pathname, const char *mode, FILE* fp);
功能:将指定的文件流重定向到打开的文件中
参数:path->文件路径
mode->打开文件的方式(同fopen)
fp->文件流指针
返回值:成功->返回文件流指针
失败->NULL
*通过代码来理解freopen重定向文件流的意思,代码如下:
//将stdout输出重新指向./test.c
fp = freopen("./test.c","w+",stdout);
//hello写入test.c文件中printf("hello\n");
//stdout是输出流,指向终端输出内容
//将stdout输出流重定向到文件test.c中后,使用printf打印数据就是向test.c文件中打印
#include
int main(int argc, char const *argv[])
{
FILE *fp;
printf("123\n");
//将stdout输出重新指向./test.c
fp = freopen("./test.c","w+",stdout);
//hello写入test.c文件中
//stdout是输出流,指向终端输出内容
//将输出流重定向到文件test.c中后,使用printf打印数据就是向test.c文件中打印
printf("hello\n");
//将stdout输出重定义到终端
freopen("/dev/tty","r+",stdout);
//world输出到终端
printf("world\n");
return 0;
}
int fclose(FILE *stream);
①功能:关闭文件;
②参数:stream->文件流;
③返回值:成功->0
失败->EOF;
#include
int main(int argc, const char *argv[])
{
//文件流fp
FILE *fp;
fp = fopen("./test.c","r");
//判断是否读取成功
if(fp == NULL)
{
//根据错误码打印错误信息
perror("fopen error");
return -1;
}
printf("fopen success\n");
//关闭文件
fclose(fp);
return 0;
}
程序内,if判断中的perror的作用是,如果找不到文件test.c,则会在终端中输出:
fopen error : No such file or directory
fopen error后面的错误提示是根据fopen函数返回的错误码输出的。
int fgetc(FILE *stream);
①功能:从文件中读取一个字符;
②参数:stream->文件流;
③返回值:成功->读到的字符;
读取失败或读到文件末尾->EOF即-1;
int fputc(int c,FILE *stream);
①功能:向文件中写入一个字符;
②参数:c->要写入的字符(单引号括起来)或者字符的ascii码;
stream->文件流;
stream形参如果传入stdout,则是输出到终端;
③返回值:成功->写入字符的ascii码;
失败->EOF;
以下两个函数可区分是失败还是读到末尾:
※ int feof(FILE * stream);
功能:判断文件有没有到结尾;
返回:到达文件末尾,返回非零值;
※ int ferror(FILE * stream);
功能:检测文件有没有出错
返回:文件出错,返回非零值;
fgetc和fputc的使用代码如下:
#include
int main(int argc, const char *argv[])
{
char ch;
FILE *fp;
fp = fopen("./a.c","r");
if(fp == NULL)
{
perror("fopen error");
return -1;
}
//读取文件a.c中的开头的一个字符
ch = fgetc(fp);
//将读取到的字符输出到终端
fputc(ch,stdout);
//关闭文件
fclose(fp);
return 0;
}
上方代码输出结果:只获取并输出a.c的第一个字符”#“,不换行。
#include
int main(int argc, const char *argv[])
{
char ch;
FILE *fp;
fp = fopen("./a.c","r");
if(fp == NULL)
{
perror("fopen error");
return -1;
}
while(1)
{
//从文件头到文件结尾,每次获取文件内的一个字符
ch = fgetc(fp);
//判断是否到文件结尾,结尾则打印提示
if(feof(fp))
{
printf("end of file\n");
break;
}
//循环向终端输出获取的字符
fputc(ch,stdout); //stdout表示输出到终端
}
//关闭文件
fclose(fp);
return 0;
}
上方代码输出结果:执行后,将会按文件a.c的内容输出到终端,并在文件内容结尾的下一行输出”end of file“。
编写代码实现cat命令的功能(查看文件的内容);
也可以将while循环中的内容改为:
char *fgets(char *s,int size,FILE *stream);
①功能:从文件中每次读取一行字符串;
②参数:s->存放该行字符串的首地址;
size->一次读取的字符个数;
stream->文件流;
③返回值:成功->s的地址;
失败或读到文件末尾:NULL;
特点:每次实际读取的字符个数是size-1个,因为会在末尾自动添加\0;
int fputs(const char *s,FILE *stream);
①功能:向文件中写字符串;
②参数:s->要写的内容;
stream->文件流;
③返回值:成功->非负整数;失败->EOF;
fgets和fputs的使用代码如下:
#include
int main(int argc, char const *argv[])
{
FILE *fp;
char buf[32];
fp = fopen("./a.c","r+");
if(NULL == fp)
{
perror("fopen err");
return -1;
}
fgets(buf,10,fp);
fputs(buf,stdout);
return 0;
}
上方代码运行结果:运行后输出a.c文件中的第一行(前提是size足够大,才能整行输出)。
#include
int main(int argc, char const *argv[])
{
FILE *fp;
char buf[32];
fp = fopen("./a.c","r+");
if(NULL == fp)
{
perror("fopen err");
return -1;
}
//只要不为空行(不包括空出来的一行,因为该行有\n,不算空行),就循环输出剩下的内容
while(fgets(buf,5,fp) != NULL)
{
fputs(buf,stdout);
}
return 0;
}
上方代码结果:按照原文件a.c输出a.c文件内的所有内容。
编写代码,用fgets函数编写“wc -l”的功能(计算文件有多少行);
#include
#include
int main(int argc, char const *argv[])
{
FILE *fp;
char buf[32];
int line = 0;
fp = fopen(argv[1],"r+");
if(NULL == fp)
{
perror("fopen err");
return -1;
}
while(fgets(buf,32,fp) != NULL)
{
//每获取一行后,如果buf的最后一个是换行“\n”,则行数加一
if(buf[strlen(buf)-1] == '\n')
{
line++;
}
}
printf("%d,%s\n",line,argv[1]);
return 0;
}
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
①功能:从文件流读取多个元素
②参数: ptr ->用来存放读取元素
size ->元素大小 sizeof(数据类型)
nmemb ->读取元素的个数
stream ->要读取的文件
③返回值:成功->读取的元素的个数;
读到文件尾->0
失败->-1
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
①功能:按对象写
②参数:同上
③返回值:成功->写的元素个数
失败 ->-1
#include
int main(int argc, char const *argv[])
{
float arr[3] = {1.23,2.34,3.45},st[3] = {0};
FILE *fp = fopen("./test.c","r+");
if(NULL == fp)
{
perror("fopen err");
return -1;
}
//将大小为float类型字节空间的3个数据写入文件中
//一个字节一个字节的读,但是float占4个字节,不能按原内容写入
fwrite(arr,sizeof(float),3,fp);
//将文件定位到开头
rewind(fp);
//读取文件的内容
fread(st,sizeof(float),3,fp);
printf("%f %f %f\n",st[0],st[1],st[2]);
fclose(fp);
return 0;
}
void rewind(FILE *stream);
功能:将文件位置指针定位到起始位置;
int fseek(FILE *stream,long offset,int whence);
①功能:文件的定位操作;
②参数:stream->文件流;
offset->偏移量->正数表示向文件尾部偏移,负数表示向文件开头偏移;
whence->相对位置;
SEEK_SET 相对于文件开头;
SEEK_CUR 相对于文件当前位置;
SEEK_END 相对于文件末尾;
③返回值:成功->0;
失败->-1。
如果本文中存在代码逻辑,代码完善,概念解释不通或不清楚的错误,请批评指正。