更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~
#fwrite和fread基本语法#
###二进制文件和文本文件的区别###
先贴出之前看到的一篇博文:http://www.cnblogs.com/zhangjiankun/archive/2011/11/27/2265184.html
这篇博文中算是比较详细的比较了文本文件和二进制文件,我看过之后,对文本文件和二进制文件的理解就是:
1 文本文件
基于字符编码的文件,一般的都是基于ASCII码。对于平时接触到的文本编辑器,editplus或者nodepad++,在打开一个文本文件的时候,都是首先寻找该文件所在的物理地址,然后从开始位置,以8个字节为单位,转换为字符,然后显示出来(可查阅ASCII码表)。
但是,在遇到一些特殊的字符(比如’\r\n’)时,文本编辑器做出相应的操作(回车、换行)。
2.二进制文件
二进制文件是基于值存储的。不仅可以存储字符信息,也可以存一些其他的结构,不局限于文本,所有的数据类型都可以存储(比如int,double, struct结构体,甚至是类)。
但是,如果用文本编辑器去打开二进制文件,会发现是乱码。原因很简单,因为文本编辑器总是定长的去识别0、1序列,遇到8个比特,就进行字符转化。而二进制文件是不定长的,比如,如果要存储一个int类型的数据,这时候需要用4个字节来表示该数据,eg:int a = 1; 其对应的二进制值00000000 00000000 00000000 00000001,这时候,文本编辑器就会解析为:NUL NUL NUL SOH。
其实,文本文件和二进制文件在物理存储上没什么区别,都是0、1序列。只是读取规则不同。
###fread & fwrite语法###
fread(object &obj, int size, int count, FILE *fp);
fwrite(object &obj, int size, int count, FILE *fp);
这两个函数总是配对使用。fwrite函数往里写的时候都是以二进制值的形式写入的,而最终该文件要以文本文件读出还是以二进制文件读出,取决于读该文件的函数。
对于fread函数,可以先用fseek函数将文件的位置指针放在序列最后,这样就可以用ftell函数得到该文件的长度(单位为字节),然后使用rewind函数使得光标复位,即回到文件开始处位置。
这里首先给出一个例子:我要往文件当中写入一个int类型的数据,int b = 2; 文件是放在工程的根目录下,文件名为text.txt.
代码如下:
#include
using namespace std;
/*
*/
void write(int *p, char *path) {
FILE *fp;
if ((fp = fopen(path, "wb")) == NULL) {
cout << "文件打开失败!" << endl;
exit(0);
}
if (fwrite(p, sizeof(int), 1, fp) != 1) {
cout << "写入失败!" << endl;
}
fclose(fp);
}
int read(char *path) {
int a;
FILE *fp;
if ((fp = fopen(path, "r")) == NULL) {
cout << "文件打开失败!" << endl;
}
fseek(fp, 0L, SEEK_END);
int len = ftell(fp);
rewind(fp);
if (fread(&a, 1, len, fp) != len) {
cout << "读取失败" << endl;
}
fclose(fp);
return a;
}
int main() {
//char *name = "I'm a student.李雷";
char *path = "./test.txt";
int b = 22;
write(&b, path);
//char *content;
int a;
a = read(path);
cout << "content:" << a << endl;
return 0;
}
代码中,只是把一个int类型的值22以二进制的方式放在了文件text.txt中,然后再读取该文件,并将读取结果打印到控制台。首先打开text.txt来看一下:
会发现是乱码,但是用函数fread()
读取文件,可以还原文件的存取内容,下图是读取结果:
如果这里往test.txt中存取的是字符串,就同文本写入一样了。
这里给出写、读字符串的代码:
#include
using namespace std;
/*
*/
void write(char *name, char *path) {
FILE *fp;
if ((fp = fopen(path, "wb")) == NULL) {
cout << "文件打开失败!" << endl;
exit(0);
}
if (fwrite(name, sizeof(char), strlen(name) + 1, fp) != (strlen(name) + 1)) {
cout << "写入失败!" << endl;
}
fclose(fp);
}
char *read(char *path) {
static char content[100];
FILE *fp;
if ((fp = fopen(path, "r")) == NULL) {
cout << "文件打开失败!" << endl;
}
fseek(fp, 0L, SEEK_END);
int len = ftell(fp);
rewind(fp);
if (fread(content, 1, len, fp) != len) {
cout << "读取失败" << endl;
}
fclose(fp);
return content;
}
int main() {
char *name = "I'm a student.李雷";
char *path = "./test.txt";
write(name, path);
char *content;
content = read(path);
cout << "content:" << content << endl;
return 0;
}
也可以读取struct结构体,即把结构体的对象作为一个整体,存入文件当中。
#include
using namespace std;
#define SIZE 1
struct attribute{
int element;
attribute *next;
};
struct test {
char name[20];
int age;
attribute *head;
};
/*
将信息以二进制的方式写入txt文件中
*/
void write(test *p1, char *path) {
FILE *fp;
if ((fp = fopen(path, "w")) == NULL) {
cout << "Can't open this file!" << endl;
exit(0);
}
for (int i = 0; i < SIZE; i++) {
if (fwrite(p1, sizeof(struct test), 1, fp) != 1) {
cout << "file write error!" << endl;
}
}
fclose(fp);
}
/*
读文件
*/
void read(test *p1, char *path) {
FILE *fp;
if ((fp = fopen(path, "r")) == NULL) {
cout << "can't open this file!!" << endl;
exit(0);
}
char buffer[100];
fseek(fp, 0L, SEEK_END); //将文件的位置指针放在最后
int len = ftell(fp); //得到文件中所有文本的长度
rewind(fp); //重新恢复位置指针的位置,回到文件的开头
for (int i = 0; i < SIZE; i++) {
if (fread(p1, sizeof(test), 1, fp) != 1) {
cout << "can't read this file." << endl;
}
cout << "name:" << p1->name << "\t" << "age:" << p1->age << endl;
}
fclose(fp);
}
/*
创建链表
*/
attribute *createLink(int *element, int count){
attribute *head = new attribute;
head->next = NULL;
attribute *tail;
attribute *newNode;
for (int i = 0; i < count; i++) {
newNode = new attribute;
newNode->next = NULL;
if (head->next == NULL) {
head->next = newNode;
} else {
tail->next = newNode;
}
tail = newNode;
}
return head;
}
int main() {
int *element;
element = (int *)malloc(sizeof(int) * 2); //动态申请2个int大小的空间
for (int i = 0; i < 2; i++) {
element[i] = i + 1;
}
test *p;
char *path = "./sss.txt";
for (int i = 0; i < SIZE; i++) {
p = new test;
cin.getline(p->name, 20); //输入姓名和年龄
cin >> p->age;
getchar();
p->head = createLink(element, 2);
}
write(p, path);
read(p, path);
return 0;
}
更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~
在这里列出与之相关的资料: