1.头文件
#include <stdio.h>
2.fopen()函数
调用fopen()函数可以打开或创建一个文件。
FILE *fopen(const char *path, const char *mode);
path : 参数 path 指向文件路径,可以是绝对路径、也可以是相对路径。
mode : 参数 mode 指定了对该文件的读写权限,是一个字符串。
返回值: 调用成功返回一个指向 FILE 类型对象的指针( FILE * ),该指针与打开或创建的文件相关联, 后续的标准 I/O 操作将围绕 FILE 指针进行。如果失败则返回 NULL ,并设置 errno 以指示错误原因。
3.fread()函数
当使用 fopen() 库函数打开文件之后,我们便可以使用 fread() 库函数对文件进行读操作
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr:fread()将读取到的数据存放在参数 ptr 指向的缓冲区中;
size:fread()从文件读取 nmemb 个数据项,每一个数据项的大小为 size 个字节,所以总共读取的数据大小为 nmemb * size 个字节。
nmemb:参数 nmemb 指定了读取数据项的个数。
stream:FILE 指针。
返回值:调用成功时返回读取到的数据项的数目(数据项数目并不等于实际读取的字节数,除非参数 size 等于 1);如果发生错误或到达文件末尾,则 fread()返回的值将小于参数 nmemb,那么到底发生了错误 还是到达了文件末尾,fread()不能区分文件结尾和错误,究竟是哪一种情况,此时可以使用 ferror()或 feof() 函数来判断。
4.fwrite()函数
对文件进行写操作
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr : 将参数 ptr 指向的缓冲区中的数据写入到文件中。
size : 参数 size 指定了每个数据项的字节大小,与 fread() 函数的 size 参数意义相同。
nmemb : 参数 nmemb 指定了写入的数据项个数,与 fread() 函数的 nmemb 参数意义相同。
stream : FILE 指针。
返回值: 调用成功时返回写入的数据项的数目(数据项数目并不等于实际写入的字节数,除非参数 size 等于 1 );如果发生错误,则 fwrite() 返回的值将小于参数 nmemb (或者等于 0 )。
5.fclose()函数
调用 fclose()库函数可以关闭一个由 fopen() 打开的文件。
int fclose(FILE *stream);
参数 stream 为 FILE 类型指针,调用成功返回 0 ;失败将返回 EOF (也就是 -1 ),并且会设置 errno 来指示错误原因。
可以根据函数的返回值判断文件是否关闭成功。
6.打开文件标识说明:
文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:
r(read): 读
w(write): 写
a(append): 追加
t(text): 文本文件,可省略不写
b(banary): 二进制文件
+: 读和写
组合含义:
"r" 打开一个用于读取的文件。该文件必须存在。
"w" 创建一个用于写入的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。
"a" 追加到一个文件。写操作向文件末尾追加数据。如果文件不存在,则创建文件。
"r+" 打开一个用于更新的文件,可读取也可写入。该文件必须存在。
"w+" 创建一个用于读写的空文件。
"a+" 打开一个用于读取和追加的文件。
"rt" 只读打开一个文本文件,只允许读数据
"wt" 只写打开或建立一个文本文件,只允许写数据
"at" 追加打开一个文本文件,并在文件末尾写数据
"rb" 只读打开一个二进制文件,只允许读数据
"wb" 只写打开或建立一个二进制文件,只允许写数据
"ab" 追加打开一个二进制文件,并在文件末尾写数据
"rt+" 读写打开一个文本文件,允许读和写
"wt+" 读写打开或建立一个文本文件,允许读写
"at+" 读写打开一个文本文件,允许读,或在文件末追加数据
"rb+" 读写打开一个二进制文件,允许读和写
"wb+" 读写打开或建立一个二进制文件,允许读和写
"ab+" 读写打开一个二进制文件,允许读,或在文件末追加数据
补充:
(1)二进制标志,文本标志,在linux下是没有区别的
(2)可以用hexdump -C 文件名 命令查看二进制文件的十六进制编码
6.fseek函数
作用:调节文件指针位置,用来设置打开文件中光标的位置。
int fseek(FILE * _File, long _Offset, int _Origin);
_File:为文件指针。
offset:为偏移量,正数表示正向偏移,负数表示负向偏移。
origin:设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、SEEK_END或SEEK_SET。
宏 | 值 | 备注 |
SEEK_CUR | 1 | 当前位置(文件指针的原本位置) |
SEEK_END | 2 | 末尾 |
SEEK_SET | 0 | 开头 |
7.ftell函数
ftell函数用于得到文件位置指针当前位置相对与文件首的偏移字节数。在随机方式存取文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置。
long len = ftell(fp)
8.使用案例(QT)
结构体:
struct Student
{
char number[20];
char name[20];
int age;
bool isman;
char phone[13];
char like[64];
};
写入数据
Student student;
memset(&student, 0, sizeof(Student));
strcpy(student.number,"20170856");
strcpy(student.name,"张三");
student.age = 20;
strcpy(student.phone,"17765852634");
strcpy(student.like,"睡觉睡觉睡觉睡觉睡觉");
student.isman = true;
FILE *fp = fopen("test", "w+");
int size = fwrite((char *)&student, 1, sizeof(Student), fp);
if(size)
{
qDebug()<<"数据保存成功。";
}
fclose(fp);
读取数据:
FILE *fp = fopen("test", "r");
Student student;
int size = fread((char*)&student, 1, sizeof(Student), fp);
qDebug()<<size;
fclose(fp);
ui->textEdit->append(QString("number:%1").arg(student.number));
ui->textEdit->append(QString("name:%1").arg(student.name));
ui->textEdit->append(QString("isman:%1").arg(student.isman));
ui->textEdit->append(QString("age:%1").arg(student.age));
ui->textEdit->append(QString("phone:%1").arg(student.phone));
ui->textEdit->append(QString("like:%1").arg(student.like));
批量数据的写入和读取
//写入
Student student;
memset(&student, 0, sizeof(Student));
strcpy(student.number,"20170856");
strcpy(student.name,"张三");
student.age = 20;
strcpy(student.phone,"17765852634");
strcpy(student.like,"睡觉睡觉睡觉睡觉睡觉");
student.isman = true;
FILE *fp = fopen("test", "w+");
for(int i = 0;i<15;i++)
{
student.age += i;
int size = fwrite((char *)&student, 1, sizeof(Student), fp);
if(size)
{
qDebug()<<"数据保存成功。";
}
}
fclose(fp);
//读取
FILE *fp = fopen("test", "r");
fseek(fp,0,2);
int size = ftell( fp ) / sizeof(Student);
qDebug()<<size;
fseek(fp,0,0);
for(int i = 0;i<size;i++)
{
Student student;
int size = fread((char*)&student, 1, sizeof(Student), fp);
qDebug()<<size;
ui->textEdit->append(QString("number:%1").arg(student.number));
ui->textEdit->append(QString("name:%1").arg(student.name));
ui->textEdit->append(QString("isman:%1").arg(student.isman));
ui->textEdit->append(QString("age:%1").arg(student.age));
ui->textEdit->append(QString("phone:%1").arg(student.phone));
ui->textEdit->append(QString("like:%1").arg(student.like));
}
fclose(fp);