一、C++中文件类型
(1)文件一般是指放在外部介质上的数据的集合。
(2)C++把文件看做是字符(字节)的序列,即由一个一个字符(字节)的数据顺序组成。
(3)根据数据的组织形式,文件分为以下两类:
1)ASCII文件(文本文件):它的每个字节存放一个ASCII码,代表一个字符。
2)二进制文件:把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。
如:整数1949,在内存中占两个字节。如果按ASCII形式输出到磁盘上,则占4个字节;如果按二进制形式输出,则在磁盘上只占2个字节。
(4)打开文件:建立一个文件流,把这个流和实际的文件相关联即为打开文件。
(5)关闭文件:完成输入输出后,取消文件和流的关联即为关闭文件。
(6)输出(写):数据由主存到外设。
(7)输入(读):数据由外设到主存。
二、文件的打开和关闭
(1)C++为文件输入输出提供了三种类型的流:输入流(ifstream)、输出流(ofstream)、输入\输出流(fstream)。
(2)文件打开的两种方式:
1、用输入输出流的成员函数open()打开。
void open(const unsigned char *, int mode, int access = filebuf::openprot);
第一个参数:用来传递文件名。
第二个参数:决定文件的打开方式。
第三个参数:决定文件的保护方式,用户通常只使用缺省值。
常用的打开方式有:
ios::in | 打开一个文件用于输入(读)操作 | |
ios::out | 打开一个文件用于输出(写)操作 | |
ios::ate | 打开一个已有的文件,文件指针指向文件尾 | |
ios::app | 以输出方式打开文件,写入的数据添加在文件末尾 | |
ios::trunc | 打开一个文件。如果文件已存在,则删除其中全部数据;如果文件不存在,则建立新文件。 | 如果已指定了ios::out,而未指定ios::app、ios::ate、ios::in,则同时默认此方式。 |
ios::nocreate | 打开一个已有文件,如果文件不存在,则打开文件失败(即不创建一个新文件) | |
ios::noreplace | 如果文件不存在,则建立新文件;如果文件存在,则打开失败。 | |
ios::binary | 指定以二进制方式打开,而不是缺省说明的文本方式。 |
2、用构造函数打开。
ifstream 对象名("文件名");
ofstream 对象名("文件名");
fstream 对象名("文件名", 打开方式);
(3)文件的关闭
当对一个打开的文件操作完毕后,应及时调用文件流的成员函数来关闭相应的文件。
流对象名.close();
三、文件的读写
(1)文本文件的读写
对文本文件的读写操作有两种方法:
1、用流输出运算符“<<”和流输入运算符“>>”输入输出标准类型的数据。
2、用文件流的put、get和getline等成员函数进行字符的输入输出。
put(char ch); //向输出流中插入一个字符ch
char get(); //用来从指定的输入流中提取一个字符(包括空白字符)
bool get(char ch); //用来从输入流中读取一个字符,赋给字符变量ch
bool get(char *ch, size_t n, char lastch); //从输入流中读取n-1个字符,赋给指定的字符数组(或字符指针指向的数组)ch,如果在读取n-1个字符之前遇到指定的终止字符lastch,则提前结束读取。
bool getline(char *ch, size_t n char lastch); //用于读入一行数据,从输入流中读取n-1个字符,赋给指定的字符数组(或字符指针指向的数组)ch,如果在读取n-1个字符之前遇到指定的终止字符lastch,则提前结束读取。
(2)二进制文件的读写
二进制文件不是以ASCII码存放数据的,它将内存中数据存储形式不加转换地传送到磁盘文件,因此它又称为内存数据的映像文件。
对二进制文件的读写主要用istream类的成员函数read和ostream类的成员函数write来实现。
istream &read(char *buffer, int len);
ostream &write(const char *buffer, int len);
(3)文件的随机读写
上述所讲为顺序文件。与顺序文件不同,随机存取文件(直接存取文件)在访问文件中的元素时,不必考虑各个元素的排列次序或位置,可根据需要访问文件中的任一个元素。
确定文件指针位置的函数:
seekg(pos); | 用于输入文件,从文件头开始,把文件指针向后移动pos个字符(字节) | seekp(pos); | 用于输出文件,从文件头开始,把文件指针向后移动pos个字符(字节) |
seekg(pos, origin); | 从指定的位置开始移动文件指针。origin有三个取值:ios::beg、ios::cur、ios::end。文件指针移动由pos指定的距离。pos为正数,表示从前向后移动文件指针;为负数,表示从后向前移动文件指针。 | seekp(pos, origin); | 从指定的位置开始移动文件指针 |
tellg(); | 用来返回文件指针的当前位置 | tellp(); | 用来返回文件指针的当前位置 |
四、实例
(1)ASCII文件的读取(指从内存读到外设)
- #include <iostream>
- #include <fstream>
- using namespace std;
- int main()
- {
- ofstream out; //输出流对象
- out.open("1.txt", ios::app); //打开文件
- out<< "我的写入程序\n"; //将数据写入到输出文件中
- out.close(); //关闭文件
- system("pause");
- return 0;
- }
找到工程所在的文件夹,可看到一个1.txt文件,打开,里面有数据:我的写入程序。
(2)ASCII文件的写入(指从外设写到内存)
- #include <iostream>
- #include <fstream>
- using namespace std;
- int main()
- {
- ifstream in("1.txt"); //输入流对象,并打开文件
- char ch[100];
- in.getline(ch, 100, '\n'); //从外设读取一行数据
- in.close(); //关闭文件
- cout<<ch<<endl;
- system("pause");
- return 0;
- }
控制台输出结果如下:
(3)二进制文件的读取(指从内存读到外设)
- #include <iostream>
- #include <fstream>
- #include <string.h>
- using namespace std;
- int main()
- {
- ofstream out; //输出流对象
- out.open("1.txt", ios::binary | ios::out); //打开文件
- //out<<"我的写入程序"; //也可实现下面的功能
- out.write("我的写入程序\n", sizeof("我的写入程序\n")); //将数据写入到输出文件中,二进制文件主要用write()函数实现
- out.close(); //关闭文件
- system("pause");
- return 0;
- }
找到工程所在的文件夹,可看到一个1.txt文件,打开,里面有数据:我的写入程序。
(4)二进制文件的写入(指从外设写到内存)
- #include <iostream>
- #include <fstream>
- #include <string.h>
- using namespace std;
- int main()
- {
- ifstream in("1.txt", ios::binary | ios::in); //输入流对象,并打开文件
- char ch[100];
- //in.getline(ch, 100, '\n'); //和下面语句的功能一样
- in.read(ch, 100); //从外设读取数据
- in.close(); //关闭文件
- cout<<ch<<endl;
- system("pause");
- return 0;
- }
控制台输出结果如下:
结果中有乱码输出是因为,1.txt中只有“我的写入程序”这几个字符,而我读取了100个,所以其他为乱码,直到遇到\0。可以在读取之前对ch进行填充:memset(ch, 0, 100);