输入输出流

文件

存储在外部介质上的数据集合;操作系统以“文件”为单位对数据进行管理

  • 根据文件内容分类:程序文件(.cpp/.obj/.exe)+数据文件

  • 根据文件存储和访问方式:顺序存取文件+随机存取文件

  • 根据文件中数据的组织形式:ASCII码文件(文本文件)+二进制文件(字节文件,节省内存和转换时间)

文件流

针对文件的操作在执行时需要手动关联磁盘文件

在C++的I/O库种定义标准输入输出流类:istream,ostream,iostream;

专用于对磁盘文件的输入输出类:ifstream(读文件),ofstream(写文件),fetream(输入输出)

文件输入/输出参数设置

方式 作用
ios::in 以输入方式打开文件,【对fstream:ios::in是 “读文件的开关”,必须写】
ios::out 以输出方式打开文件,文件已存在则原有内容会被清除(只有ofstream默认)
ios::app 一、先给核心结论(以输出方式打开文件,数据追加在文件末尾【不然直接打开会被清空原有的】
ios::ate 打开一个已有文件,文件指针指向文件末尾
ios::trunc 打开文件,若已存在就删除其中全部数据,不存在就新建一个【强制清空】
ios::binary 以二进制方式打开文件,不指定的话会默认ASCII
ios::in | ios::out 以输入输出方式打开文件,文件可读可写
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
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {
// ========== 1. ios::out模式(写文件):老师的紧凑写法 ==========
ofstream out_file;
if (!out_file.open("test_table.txt")) { // 打开+检查一步到位
cout << "打开文件失败(out模式)" << endl;
return 1;
}
out_file << "这是ios::out模式写入的内容(会清空原有内容)" << endl;
out_file.close();

// ========== 2. ios::app模式(追加):老师的紧凑写法 ==========
ofstream app_file;
if (!app_file.open("test_table.txt", ios::app)) { // 打开+检查一步到位
cout << "打开文件失败(app模式)" << endl;
return 1;
}
app_file << "这是ios::app模式追加的内容(加在末尾)" << endl;
app_file.close();

// ========== 3. ios::in模式(读文件):老师的紧凑写法 ==========
ifstream in_file;
if (!in_file.open("test_table.txt")) { // 打开+检查一步到位(等价于ios::in)
cout << "打开文件失败(in模式)" << endl;
return 1;
}
cout << "===== 读取test_table.txt的内容 =====" << endl;
string line;
while (getline(in_file, line)) {
cout << line << endl;
}
in_file.close();

return 0;
}

文本文件操作

文本文件:以ASCII码存档数据,一个字节对应一个字符

在磁盘文件中有一个文件读写位置标记,来指明当前进行读写的位置

方式 作用
ios::beg 文件开头,是默认值
ios::cur 标记文件当前位置
ios::end 文件末尾

【例】文本文件f4.dat中存放着若干行英文,编写程序将其中的小写字母全部修改为大写字母,再存入磁盘文件f4.dat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void modify(){
fstream file("f4.dat",ios::in |ios::out);
if(!file){
cerr<<"open f4.dat error"<<endl; //cerr是「错误输出流」,专门输出错误信息
exit(1);
}
string line = "",content = "";
while(!file.eof()){ //.eof就是end of file 这句就是如果没到文件末尾
getline(file,line); //从文件中读一整行
content.append(line); //字符串合并
content.append("\n"); //添换行符
}
int i,n = content.length();
for(i=0;i<n;i++){
if(content[i]>='a'&&content[i]<='z')content[i]=content[i]-32;
}
file.clear();
file.seekp(ios::beg); //定位到文件开头
file<<content<<endl;//写入新内容
file.close();
}

二进制文件操作

操作时用用成员函数read()和write()读写二进制数据;

用fstream类定义iofile文件流对象(另外俩不行),以二进制模式进行读写操作

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
#include <iostream>
#include <fstream>
using namespace std;

// 定义一个简单的结构体(要读写的二进制数据)
struct Student {
char name[20]; // 姓名(用char数组,避免string的二进制读写问题)
int age; // 年龄
float score; // 分数
};

int main() {
// ========== 第一步:用write()写二进制文件 ==========
// 1. 准备要写入的数据
Student stu = {"张三", 18, 95.5};
// 2. 打开文件:二进制+写模式(ios::binary | ios::out)
ofstream out_file("student.dat", ios::binary | ios::out);
if (!out_file) {
cerr << "打开写入文件失败!" << endl;
return 1;
}
// 3. 写二进制数据:&stu取结构体地址,转char*,sizeof(stu)是字节数
out_file.write((char*)&stu, sizeof(Student));
out_file.close(); // 写完关闭

// ========== 第二步:用read()读二进制文件 ==========
// 1. 定义空结构体,存储读取的数据
Student stu_read;
// 2. 打开文件:二进制+读模式(ios::binary | ios::in)
ifstream in_file("student.dat", ios::binary | ios::in);
if (!in_file) {
cerr << "打开读取文件失败!" << endl;
return 1;
}
// 3. 读二进制数据:&stu_read是存储地址,转char*,sizeof(Student)是要读的字节数
in_file.read((char*)&stu_read, sizeof(Student));
in_file.close(); // 读完关闭

// ========== 第三步:打印读取的结果 ==========
cout << "从二进制文件读取的数据:" << endl;
cout << "姓名:" << stu_read.name << endl;
cout << "年龄:" << stu_read.age << endl;
cout << "分数:" << stu_read.score << endl;

return 0;
}