c++文件读写之fread和fwrite
2015-03-31 16:05
357 查看
fwrite和fread基本语法
二进制文件和文本文件的区别
先贴出之前看到的一篇博文:/article/7049548.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<iostream> 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<iostream> 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<iostream> 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; }
sss.txt中仍然是乱码:
如果以16进制查看该文件,可看到如下结果:
在这里列出与之相关的资料:
1. /article/7049548.html
2. http://www.cnblogs.com/witxjp/archive/2011/03/21/1990519.html
3. http://blog.csdn.net/athenaer/article/details/7876614
4. /article/2319277.html
5. /article/8417867.html
6. http://www.cnblogs.com/witxjp/archive/2011/03/21/1990519.html
相关文章推荐
- C/C++读写文件(fwrite,fread)
- C++ 文件读写函数之——fopen、fread和fwrite
- (转载)C++文件读写函数之——fopen、fread和fwrite、fgetc和fputc、fgets和fputs、ftellf和fseek、rewind
- C++ 文件读写函数之——fopen、fread和fwrite
- C++文件读写函数之——fopen、fread和fwrite、fgetc和fputc、fgets和fputs、ftellf和fseek、rewind
- C++文件读写函数之——fopen、fread和fwrite、fgetc和fputc、fgets和fputs、ftellf和fseek、rewind
- C++文件读写函数之——fopen、fread和fwrite、fgetc和fputc、fgets和fputs、ftellf和fseek、rewind
- C++文件读写函数之——fgets和fputs、fread和fwrite、fscanf和fprintf
- 读写大“二进制”文件,不必申请很大内存(fopen,fread,fwrite,fclose)
- fstream与 C 风格(例如fread 和 fwrite )两种读写文件方法的效率比较
- C 语言 fwrite 和 fread 文件读写操作示例
- C/C++文件的操作(fread() fwrite())
- C语言文件读写常识(fseek, ftell, fread, fwrite, fopen)
- 文件读写操作之一 <二进制读写操作> fwrite与fread
- fread()和fwrite()函数读写文件操作
- php高并发状态下文件的读写(fopen,fwrite,fread)
- 读写文件 fread,fwrite
- C语言:用二进制方式向文件读写一组数据(fread、fwrite)
- PHP读写大“二进制”文件,不必申请很大内存(fopen、fread、fwrite、fclose)
- C/C++文件的操作(fread() fwrite())