大家好,我是练习编程时长两年半的个人练习生昆工第一ikun,今天我们来分享一下标准IO相关函数库的介绍与使用,话不多话,开团!!!!!
目录
一、标准IO相关库函数
fopen() / fclose() -- 打开/关闭文件
fgetc() / fputc() -- 按字节读写文件
fgets() / fputs() -- 按行读写文件
fread() / fwrite() -- 按对象读写文件
ftell() / fseek() / rewind() -- 定位文件
fflush() -- 刷新流
feof() -- 判断错误流
1.打开文件 -- fopen()
#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
参数:
pathname:打开文件的文件名(包含路径)
mode:打开文件的方式
r:以只读的方式打开文件,文件必须要存在
r+:以读写方式打开文件,文件必须要存在
w: 以只写方式打开文件,如果文件不存在,则会先创建再打开
w+: 以读写方式打开文件,如果文件不存在,则会先创建再打开
a: 以只写方式打开文件,如果文件不存在,则会先创建再打开
a+: 以读写方式打开文件,如果文件不存在,则会先创建再打开
返回值:
成功返回对应的文件的流指针,失败返回NULL,并且设置错误号(errno)
errno:当前系统中最后一个错误的编号
----------------------------------------------------------------------------
#include <string.h>
char *strerror(int errnum);
参数:
errnum:错误号
返回值:
成功返回错误原因
-----------------------------------------------------------------------------
#include <stdio.h>
void perror(const char *s);
参数:
s:提示信息
2.关闭文件 -- fclose()
#include <stdio.h>
int fclose(FILE *stream);
参数:
stream:关闭文件对应的流指针
返回值:
成功返回0,失败返回-1;
3.按字节读写 -- fgetc()/fputc()
#include <stdio.h>
int fgetc(FILE *stream);
参数:
stream:流指针
返回值:
成功返回读取的字符,失败返回-1;
读到文件末尾也会返回-1;
-----------------------------------------------------------------------------
#include <stdio.h>
int fputc(int c, FILE *stream);
参数:
c:输入的字符
stream:流指针
返回值:
成功返回写入的字符,失败返回-1;
4.按行读写 -- fgets()/fputs()
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
参数:
s:字符串首地址
size:请求读取数据的最大长度
stream:流指针
返回值:
成功返回得到字符串的首地址,失败返回NULL;
注意:
①当读取的内容遇到换行符,读取内容结束
②最大读取内容为 size-1 个
---------------------------------------------------------------------------
int fputs(const char *s, FILE *stream);
参数:
s:写入字符串的首地址
stream:流指针
返回值:
失败返回-1;
实例:
编写一个程序,实现两个文件之间内容的复制
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
if(argc < 3){
printf("usage:%s <src_filename> <dst_filename>\n", argv[0]);
return -1;
}
FILE *fp1 = fopen(argv[1], "r");
if(NULL == fp1)
{
perror("open argv[1]");
return -1;
}
FILE *fp2 = fopen(argv[2], "w+");
if(NULL == fp2)
{
perror("open argv[2]");
return -1;
}
char buf[64];
while(fgets(buf, 64, fp1) != NULL)
{
fputs(buf, fp2);
memset(buf, 0, 64);
}
printf("复制成功!\n");
return 0;
}
我们当前目录下有一个文件 cxk.txt,里面的内容是54行歌词,我们要将它复制到另一个文件rap.txt中,运行程序
我们可以看到,运行程序后,当前目录下创建了一个文件rap.txt,并且将cxk.txt的内容复制到了rap.txt中,程序功能实现完毕。
5.按对象读写
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
返回值:
ptr:存放字符串的首地址
size:对象大小
nmemb:对象个数
stream:流指针
返回值:
成功返回读到的对象个数,失败返回0;
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
参数:
ptr:存放字符串的首地址
size:对象大小
nmemb:对象个数
stream:流指针
返回值:
成功返回读到的对象个数,失败返回0;
6.刷新流 -- fflush()
#include <stdio.h>
int fflush(FILE *stream);
参数:
stream:流指针
返回值:
成功返回0,失败返回-1;
7.文件定位
#include <stdio.h>
long ftell(FILE *stream);
功能:
返回文件指针相对于文件开头的偏移量
参数:
stream:流指针
返回值:
成功返回文件指针相对于文件开头的偏移量,失败返回-1;
文件指针最后定位位置 == offset + whence
int fseek(FILE *stream, long offset, int whence);
参数:
stream:流指针
offset:偏移量,可正可负
whence:基准点
SEEK_SET:将文件指针定位在文件开头
SEEK_CUR:将文件指针定位在当前位置
SEEK_END:将文件指针定位在文件末尾
返回值:
成功返回0,失败返回-1;
void rewind(FILE *stream);
功能:
将文件指针定位在文件开头
8.判断错误流 -- feof()
#include <stdio.h>
int feof(FILE *stream);
返回值:
1 -- 流访问结束
0 -- 错误返回
二、实例
打开一个文件,向文件中每隔1s记录当前行数和时间,并且下一次运行程序时,行数要接着上一次
代码如下:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *fp = fopen("1.txt", "a+");
if(NULL == fp)
{
perror("open");
return -1;
}
int i = 0, n = 1;
char buf[64];
while(fgets(buf, 64, fp) != NULL) //计算行数
{
if(buf[strlen(buf)-1] == '\n')
{
n++;
}
memset(buf, 0, 64);
}
time_t my_t;
while(i < 60){ //设置自由秒数输入
sleep(1);
time(&my_t);
struct tm *t = localtime(&my_t);
printf("第%d秒\n", t->tm_sec); //在终端打印输入的次数
fprintf(fp, "第%d行:%d年%d月%d日%d:%d:%d\n", n, t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); //将当前时间以年月日时分秒的格式存储到文件之中
if(i == 59)
{
i = 0;
}
i++;
n++; //记录行数
fflush(fp); //刷新流,以便手动停止
}
return 0;
}
可以看到,在运行程序之前我们当前的目录下没有1.txt这个文件,在运行程序后,创建了一个1.txt文件并且将当前的时间按秒记录到1.txt中。如下图所示:
然后,我们再次运行程序,可以发现行号接着上次的19开始输入
到这里,功能实现完毕,这个实例里用到了时间函数time,localtime,还用到了fprintf函数,大家有不知道这三个函数用法的可以用man手册获取用法及函数原型。
今天分享的内容就到这里了,如果大家喜欢可以三连一波,我是练习编程时长两年半的个人练习生昆工第一ikun,我们明天见。