- 文件 *** 作
- C++中的文件 *** 作时基于面向对象的
- C++中文件类型分为两种:
- *** 作文件的三大类(这些类都属于标准模板库):
- 1 文本文件
- 1.1 写文件
- 写文件步骤如下:
- 文件打开方式:
- 1.2 读文件
- 读取文件数据的四种方式
- 按照喜好记前三个中的一个就行
- 综合
- 2 二进制文件(不仅可以 *** 作内置数据类型还可以 *** 作自定义数据类型)
- 注意打开方式要指定为 ==ios::binary==
- 2.1 写文件
- 注意:对文件 *** 作时,字符串最好使用C语言风格的字符串(也就是字符数组)因为wirte()和read函数()都包含参数char *,用string会引发错误
- 2.2 读文件
- 步骤
- 注意事项:
文件 *** 作
视频链接
程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放
通过文件可以将数据持久化
C++中对文件 *** 作需要包含头文件 < fstream >
C++中文件类型分为两种:
- 文本文件 - 文件以文本的ASCII码形式存储在计算机中
- 二进制文件 - 文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们
*** 作文件的三大类(这些类都属于标准模板库):
- ofstream(output):写入文件 *** 作
- ifstream(input): 读取数据 *** 作
- fstream : 读写 *** 作。一般使用这个类进行文本 *** 作
1 文本文件 1.1 写文件 写文件步骤如下:
-
包含头文件
#include
-
创建流对象
ofstream ofs;
-
打开文件
ofs.open(“文件路径”,打开方式);
文件路径可以直接写个文件名,因为如果不指定路径的话,他会默认在当前项目路径下。 -
写数据
ofs << “写入的数据”;
类似于cout<<“…”; cout就是往屏幕上输出,而ofs就是往文件里输出 -
关闭文件,这一步很重要而且容易遗漏
ofs.close();
#include
using namespace std;
#include
// 1.包含头文件 fstream
#include
// 文本文件 写文件
void test01() {
// 1.包含头文件
// 2.创建流对象
ofstream ofs;
// 3.指定打开的方式
//文件名为test.txt
ofs.open("test.txt", ios::out);
// 4.写内容
ofs << "姓名:张三" << endl << "年龄:19" << endl << "性别:男" << endl;
// 5.关闭文件
ofs.close();
}
int main() {
test01();
cin.get();
return 0;
}
总结:
- 文件 *** 作必须包含头文件 fstream
- 读文件可以利用 ofstream ,或者fstream类
- 打开文件时候需要指定 *** 作文件的路径,以及打开方式
- 利用<<可以向文件中写数据
- *** 作完毕,要关闭文件
1.2 读文件
读文件与写文件步骤相似,但是读取方式相对于比较多
读文件步骤如下:
-
包含头文件
#include
-
创建流对象
ifstream ifs;
-
打开文件并判断文件是否打开成功
ifs.open(“文件路径”,打开方式);
-
读数据
四种方式读取
-
关闭文件,记住别忘了要关闭文件
ifs.close();
判断文件是否打开成功(其实也就是判断有没有这个文件):
if (!ifs.is_open())
{
cout << "文件打开失败" << endl;
return;
}
if_open()是系统自带的布尔类型函数,打开成功返回1
打开失败返回0(这个函数是判断文件是否存在的)
读取文件数据的四种方式 按照喜好记前三个中的一个就行
- 第一种方式:把文件内容全部放在字符数组中
//第一种方式
char buf[1024] = { 0 };//首先初始化字符数组
while (ifs >> buf)
// ifs右移运算符,他会读取数据并放到buf数组中,当数据全部读完后,返回一个false,while循环也就结束了
{
cout << buf << endl;
}
- 第二种方式:使用ifs.getline()函数
ifs.getline(char *str,count)中有两个参数;
char *str:表示我们要把读取的数据放到哪个地方,一般是个数组
count:所占的空间
//第二种
char buf[1024] = { 0 };
while (ifs.getline(buf,sizeof(buf)))
{
cout << buf << endl;
}
- 第三种方式:把内容放到string字符串中
包含头文件include
然后使用函数getline(输入流对象,准备好的字符串)
//第三种
string buf;
while (getline(ifs, buf))
{
cout << buf << endl;
}
- 不太推荐的第四种方式:他会将文件中的所有数据一个一个地读出来,放到字符C里边。效率太差
ifs.get()每次只读一个字符。EOF代表末尾的意思
// 第四种
char c;
while ((c = ifs.get()) != EOF)
{
cout << c;
}
综合
#include
using namespace std;
//1. 包含头文件
#include
#include
void test01()
{ // 2. 创建流对象
ifstream ifs;
//3. 打开文件并判断文件是否打开成功
ifs.open("test.txt", ios::in);
if (!ifs.is_open())
{
cout << "文件打开失败" << endl;
return;
}
// 4. 读数据
// 四种方式
//第一种方式
//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;
//}
// 5. 关闭文件
ifs.close();
}
int main() {
test01();
system("pause");
return 0;
}
2 二进制文件(不仅可以 *** 作内置数据类型还可以 *** 作自定义数据类型)
以二进制的方式对文件进行读写 *** 作
注意打开方式要指定为 ios::binary2.1 写文件
二进制方式写文件主要利用流对象调用成员函数write
函数原型 :ostream& write(const char * buffer,int len);
参数解释:参数一:字符指针常量buffer(也可以理解为就是一段地址(指针就是地址),不过要把它强制转换成const char * ) 。 buffer指向内存中一段存储空间。len是读写的字节数
数组名就可以直接作为参数一,当传数组给一个函数时,数组类型自动转换为指针类型,传的实际是数组元素首地址。
注意:对文件 *** 作时,字符串最好使用C语言风格的字符串(也就是字符数组)因为wirte()和read函数()都包含参数char *,用string会引发错误
#include
using namespace std;
#include
#include
class Person
{
public:
char m_Name[64];
int m_Age;
};
//二进制文件 写文件
void test01()
{
//1、包含头文件
//2、创建输出流对象
ofstream ofs("person.txt", ios::out | ios::binary|ios::trunc);
//3、打开文件
//ofs.open("person.txt", ios::out | ios::binary);
int a = 55;
int d[20];
for (int i = 0; i < 20; i++) {
d[i] = i;
}
Person p = { "张三" , 18 };
char c[15] = { "Hello,World!" };
//4、写文件
ofs.write((const char*)&a, sizeof(a));
ofs.write((const char*)d, sizeof(c));
ofs.write((const char*)&p, sizeof(p));
ofs.write((const char*)c, sizeof(c));
//5、关闭文件
ofs.close();
}
int main() {
test01();
system("pause");
return 0;
}
二进制文件打开是乱码
2.2 读文件
二进制方式读文件主要利用流对象调用成员函数read
函数原型:istream& read(char *buffer,int len);
参数解释:参数一:字符指针buffer(也可以理解为就是一段地址(指针就是地址),不过要把它强制转换成 char * ) 。它指向内存中一段存储空间。len是读写的字节数
数组名可以直接作为参数一,当传数组给一个函数时,数组类型自动转换为指针类型,传的实际是数组元素首地址。
步骤
- 包含头文件
- 创建流对象
- 打开文件并判断文件是否打开成功
- 将二进制数据转换为可读数据
- 打印转换后的可读数据
- 关闭文件
#include
using namespace std;
// 1.包含头文件
#include
#include
class Person
{
public:
char m_Name[64];
int m_Age;
};
void test01()
{
// 2.创建流对象的同时打开文件
ifstream ifs("person.txt", ios::in | ios::binary);
// 3.判断文件是否打开成功
if (!ifs.is_open())
{
cout << "文件打开失败" << endl;
}
Person p;
// 4.将二进制数据转换为可读数据
// 这一步不能将数据读出到屏幕上,这一步的作用只是把二进制数据转换为可读数据
int d;
int z[20];
char c[15];
ifs.read((char*)&d, sizeof(d));
ifs.read((char*)z, sizeof(z));
ifs.read((char*)&p, sizeof(p));
ifs.read((char*)c, sizeof(c));
// 5.打印转换后的可读数据
// 用cout即可读出数据
cout << "d=" << d << endl;
cout << "姓名: " << p.m_Name << " 年龄: " << p.m_Age << endl;
for (int i = 0; i < 20; i++) {
cout << z[i] << endl;
}
for (int i = 0; i < 15; i++) {
cout << c[i];
}
cout << endl;
// 6.关闭文件
ifs.close();
}
int main() {
test01();
system("pause");
return 0;
}
- 把什么数据类型写入文件,查看文件时就要用相应的数据类型来接受。
比如用write函数写入一个整形数组:
int c[20];
ifs.read((char*)c, sizeof(c));
那么read函数接受时也应用整形数组来接受:
int z[20];
ifs.read((char*)z, sizeof(z));
- 用write函数按某一顺序写入了多个数据类型时,read函数查看时也应与写入时的顺序一样
比如按下列顺序用write函数写入了以下四个数据类型:
int a = 55;
int d[20];
Person p = { "张三" , 18 };
char c[15] = { "Hello,World!" };
//4、按下列顺序写入文件
ofs.write((const char*)&a, sizeof(a));
ofs.write((const char*)d, sizeof(c));
ofs.write((const char*)&p, sizeof(p));
ofs.write((const char*)c, sizeof(c));
read函数查看时也得与写入时的顺序相同:
int d;
int z[20];
char c1[15];
Person p1;
// 注意各个read函数的顺序
ifs.read((char*)&d, sizeof(d));
ifs.read((char*)z, sizeof(z));
ifs.read((char*)&p1, sizeof(p1));
ifs.read((char*)c1, sizeof(c1));
不能写成下面这样:
int d;
int z[20];
char c1[15];
Person p1;
ifs.read((char*)&d, sizeof(d));
ifs.read((char*)c1, sizeof(c1));
ifs.read((char*)z, sizeof(z));
ifs.read((char*)&p1, sizeof(p1));
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)