ofstream需要头文件fstream
原型如下:
explicit fstream (const char* filename, ios_base::openmode mode = ios_base::in | ios_base::out);
将数据写入到文件(filename)中,第二个参数是打开文件的模式
默认是ios_base::in(读取) 或 ios_base::out(写入)
C++中, ios_base::out模式等价于 ios_base::out | ios_base::trunc(文件存在,则截短文件,也就是覆盖原内容)
ifstream 需要头文件 istream
原型如下:
explicit ifstream (const char* filename, ios_base::openmode mode = ios_base::in);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 1 string filename;
2 cout << "文件名:";
3 cin >> filename;
4 ofstream fout(filename.c_str());
5 fout << "look look look.\n";
6 cout << "输入secret = ";
7 float secret;
8 cin >> secret;
9 fout << "secret = " << secret << endl;
10 fout.close();
11
12 ifstream fin(filename.c_str());
13 cout << "文件名为:" << filename << endl;
14 char ch;
15 while (fin.get(ch))//每次读取一个字符给ch
16 cout << ch;
17 cout << "Done\n";
18 fin.close();
19
20
第二个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 1 const char *file = "guest.txt";
2 char ch;
3 ifstream fin;
4 fin.open(file, ios_base::in);
5
6 if (fin.is_open())//判断文件是否打开且与流关联,打开且关联就为真
7 {
8 cout << "文件:" << file << "内容如下:" << endl;
9 while (fin.get(ch))
10 {
11 cout << ch;
12 }
13 fin.close();
14 }
15
16 ofstream fout;
17 fout.open(file, ios_base::out | ios_base::app);
18 if (!fout.is_open())
19 {
20 cout << "文件没有被打开" << endl;
21 return 0;
22 }
23 cout << "宾客名:";
24 string name;
25 while (getline(cin, name) && name.length() > 0)
26 {
27 fout << name << endl;
28 }
29 fout.close();
30
31 fin.clear();
32 fin.open(file, ios_base::in);
33 if (fin.is_open())
34 {
35 cout << "宾客如下:" << endl;
36 while (fin.get(ch))
37 cout << ch;
38 }
39 fin.close();
40
41
42
二进制模式的文件操作
二进制模式和文本模式有很大的差别
文本格式便于读取,可以很方便的将文件从一个计算机系统传入到另一个计算机系统
二进制模式对于存储数字比较精准,因为它存储的值是内部表示,不会有转换误差或舍入误差,保存数据更快,不需要转换,可以大块的存储数据。
写入文件
fout.write( (char*)&p1, sizeof(p1));
读取文件
fin.read( (char*)&p1, sizeof(p1));
ios_base::binary二进制模式
setw()需要头文件iomanip
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 1 const int LIM = 20;
2 struct planet
3 {
4 char name[LIM];
5 double p;
6 double g;
7 };//大小40个字节
8
9
10 char *filename2 = "planets.dat";
11 planet p;
12 ifstream fin;
13 fin.open(filename2, ios_base::in | ios_base::binary);
14 if (fin.is_open())
15 {
16 cout << "文件:" << filename2 << "内容如下:" << endl;
17 while (fin.read((char*)&p, sizeof(p)))
18 {
19 cout << setw(20) << p.name << endl;
20 cout << setw(20) << p.p << endl;
21 cout << setw(20) << p.g << endl;
22 }
23 fin.close();
24 }
25
26
27 ofstream fout;
28 fout.open(filename2, ios_base::out | ios_base::app | ios_base::binary);
29 if (!fout.is_open())
30 {
31 cout << "文件打开失败" << endl;
32 exit(EXIT_FAILURE);
33 }
34
35 cout << "输入新的信息" << endl;
36 cout << "name : " << endl;
37 cin.getline(p.name, 20);
38 while (p.name[0] != '\0')//第一个字符不是\0,则就不是空字符串
39 {
40 cout << "p : ";
41 cin >> p.p;
42 cout << "g : ";
43 cin >> p.g;
44
45 fout.write((char*)&p, sizeof(p));
46
47 cout << "输入新的信息" << endl;
48 cout << "name : \n";
49 while (cin.get() != '\n')//上边的endl被cin读取到了,这里进行清除
50 {
51 continue;
52 }
53 cin.getline(p.name, 20);
54 }
55 fout.close();
56
57
58 fin.open(filename2, ios_base::in | ios_base::binary);
59 if (fin.is_open())
60 {
61 cout << "文件:" << filename2 << "内容如下:" << endl;
62 while (fin.read((char*)&p, sizeof(p)))
63 {
64 cout << setw(20) << p.name << endl;
65 cout << setw(20) << p.p << endl;
66 cout << setw(20) << p.g << endl;
67 }
68 fin.close();
69 }
70
71
第一次运行
第二次运行
随机存取
常用于二进制模式的文件
seekg() 将输入指针移动到指定的文件位置
seekp() 将输出指针移动到指定的文件位置
原型
istream& seekg (streampos pos);
istream& seekg (streamoff off, ios_base::seekdir way);
streamoff的值被用来度量相对于文件特定位置的偏移量(单位为字节)
等于0 当前位置
大于0 后移
小于0 前移
fin.seekg(30, ios_base::beg);//在当前位置,将输入指针向后移动30字节
ios_base::beg 文件开始处的偏移量
ios_base::cur 文件当前位置的偏移量
ios_base::end 文件尾的偏移量
streampos pos 文件开始处的位置,移动的偏移量,单位是字节,第一个字节编号为0
fin.seekg(112);//表示文件指针向后移动到第113个字节
原型
ostream& seekp (streampos pos);
ostream& seekp (streamoff off, ios_base::seekdir way);
参数和seekp的类似