6. 文件读写操作
程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放
通过文件可以将数据持久化
C++中对文件操作需要包含头文件 <fstream>
文件类型分为两种:
- 文本文件 - 文件以文本的ASCII码形式存储在计算机中
- 二进制文件 - 文件以文本的二进制形式存储在计算机中
操作文件的三大类:
ofstream
:写操作ifstream
: 读操作fstream
: 读写操作
6.1 文本文件
6.1.1 写文件
写文件步骤如下:
-
包含头文件
#include <fstream>
-
创建流对象
ofstream ofs;
-
打开文件
ofs.open("文件路径",打开方式);
-
写数据
ofs << "写入的数据";
-
关闭文件
ofs.close();
文件打开方式:
打开方式 | 解释 |
---|---|
ios::in | 为读文件而打开文件 |
ios::out | 为写文件而打开文件 |
ios::ate | 初始位置:文件尾 |
ios::app | 追加方式写文件 |
ios::trunc | 如果文件存在先删除,再创建 |
ios::binary | 二进制方式 |
注意: 文件打开方式可以配合使用,利用|操作符
**例如:**用二进制方式写文件 ios::binary | ios:: out
示例:
#include <fstream> // 头文件
void test01()
{
ofstream ofs; // 流对象
ofs.open("test.txt", ios::out); // 打开文件
ofs << "姓名:张三" << endl; // 写入数据
ofs << "性别:男" << endl;
ofs << "年龄:18" << endl;
ofs.close(); // 关闭文件
}
int main()
{
test01();
return 0;
}
6.1.2 读文件
读文件步骤如下:
-
包含头文件
#include <fstream>
-
创建流对象
ifstream ifs;
-
打开文件并判断文件是否打开成功
ifs.open("文件路径",打开方式);
-
读数据 四种方式读取
char buf[1024] = { 0 };
while (ifs >> buf); // 第一种
char buf[1024] = { 0 };
while(ifs.getline(buf,sizeof(buf))); // 第二种
string buf;
while(getline(ifs, buf)); // 第三种
char c;
while((c = ifs.get()) != EOF); // 第四种
- 关闭文件
ifs.close();
#include <fstream>
#include <string>
void test01()
{
ifstream ifs;
ifs.open("test.txt", ios::in);
if (!ifs.is_open())
{
cout << "文件打开失败" << endl;
return;
}
// 第一种
//char buf[1024] = { 0 };
//while (ifs >> buf)
//{
// cout << buf << endl;
//}
// 第二种
//char buf[1024] = { 0 };
//while (ifs.getline(buf,sizeof(buf)))
//{
// cout << buf << endl;
//}
// 第三种
//string buf;
//while (getline(ifs, buf))
//{
// cout << buf << endl;
//}
char c;
while ((c = ifs.get()) != EOF)
{
cout << c;
}
ifs.close();
}
int main()
{
test01();
return 0;
}
6.2 二进制文件
以二进制的方式对文件进行读写操作
打开方式要指定为 ios::binary
6.2.1 写文件
二进制方式写文件主要利用流对象调用成员函数write
函数原型 :ostream& write(const char * buffer,int len);
参数解释:字符指针buffer指向内存中一段存储空间, len 是读写的字节数
示例:
#include <fstream> //1、包含头文件
#include <string>
class Person
{
public:
char m_Name[64];
int m_Age;
};
//二进制文件 写文件
void test01()
{
//2、创建输出流对象
ofstream ofs("person.txt", ios::out | ios::binary);
//3、打开文件
//ofs.open("person.txt", ios::out | ios::binary);
Person p = {"张三" , 18};
//4、写文件
ofs.write((const char *)&p, sizeof(p));
//5、关闭文件
ofs.close();
}
int main()
{
test01();
return 0;
}
ofstream ofs(“person.txt”, ios::out | ios::binary);
等同于
ofstream ofs;
ofs.open(“person.txt”, ios::out | ios::binary);
6.2.2 读文件
二进制方式读文件主要利用流对象调用成员函数read
函数原型:istream& read(char *buffer,int len);
参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数
示例:
#include <fstream>
#include <string>
class Person
{
public:
char m_Name[64];
int m_Age;
};
void test01()
{
ifstream ifs("person.txt", ios::in | ios::binary);
if (!ifs.is_open())
{
cout << "文件打开失败" << endl;
}
Person p;
ifs.read((char *)&p, sizeof(p));
cout << "姓名: " << p.m_Name << " 年龄: " << p.m_Age << endl;
}
int main()
{
test01();
return 0;
}
6.3 综合案例——罚抄100000遍对不起
#include <map>
#include <string>
#include <fstream>
#include <queue>
static const std::map<int, std::string> xuhao = {{1, "一"}, {2, "二"}, {3, "三"}, {4, "四"}, {5, "五"}, {6, "六"}, {7, "七"}, {8, "八"}, {9, "九"}, {10, "十"}, {100, "百"}, {1000, "千"}, {10000, "万"}};
std::string num2Chinese(int num)
{
std::string cn;
int n = num, pre = 0;
for (auto it = xuhao.crbegin(); it != xuhao.crend(); it++) // 从后开始遍历iterator
{
int count = 0;
for (; n >= it->first; n -= it->first)
++count;
if (!count) // 如果还没找到最高位
continue;
if (pre / 10 > it->first)
cn += "零";
if (it->first >= 10 && (count != 1 || num > 20))
cn += xuhao.at(count);
cn += it->second;
pre = it->first;
}
return cn;
}
int main()
{
std::string all_line;
for (int i = 1; i <= 100000; ++i)
all_line += "对不起 第" + num2Chinese(i) + "遍\n";
std::ofstream ofs("sorry.txt");
ofs << all_line;
}
输出:
对不起 第一遍
对不起 第二遍
对不起 第三遍
…
对不起 第九万九千九百九十七遍
对不起 第九万九千九百九十八遍
对不起 第九万九千九百九十九遍
对不起 第十万遍