文件操作
程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放
通过文件可以将数据持久化
C++中对文件操作需要包含头文件**<fstream>**
文件类型分为两种:
1.文本文件: 文件以文本的ASCII码 形式存储在计算机中
2.二进制文件: 文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们
操作文件的三大类:
1. ofstream:写操作
2. ifstream:读操作
3. fstream:读写操作5.1文本文件
5.1.1写文件
写文件步骤如下:
- 包含头文件
#include <fstream>- 创建流对象
ofstream ofs;- 打开文件
ofs.open("文件路径",打开方式);- 写数据
ofs <<"写入的数据";- 关闭文件
ofs.close();文件打开方式
注意 :文件打开方式可以配合使用,利用 | 操作符
例如:用二进制方式写文件 ios::binary | ios:out
cpp#include <fstream> void test01() { ofstream ofs; ofs.open("test.txt",ios::out); ofs<<"姓名:张三" << endl; ofs<<"性别:男" << endl; ofs<< "年龄:18"<< endl; ofs.close(); } int main() { test01(); system("pause"); return 0; }
总结:
- 文件操作必须包含头文件fstream
- 读文件可以利用ofstream,或者fstream类
- 打开文件时候需要指定操作文件的路径,以及打开方式
- 利用<<可以向文件中写数据
- 操作完毕,要关闭文件
5.1.2读文件
读文件与写文件步骤相似,但是读取方式相对于比较多
读文件步骤如下:
- 包含头文件
#include <fstream>
- 创建流对象
ifstream ifs;
3.打开文件并判断文件是否打开成功
ifs.open("文件路径"打开方式):
- 读数据
四种方式读取
- 关闭文件
ifs.close();
示例:
cpp#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 //while((c = ifs.get()) != EOF ) //EOF end of file //{ cout << c; //} char c; while ((c = ifs.get()) != EOF) { cout << c; } ifs.close(); } int main() { test01(); system("pause"); return 0; }
总结:
- 读文件可以利用ifstream,或者fstream类
- 利用is_open函数可以判断文件是否打开成功
- close关闭文件
5.2二进制文件
以二进制的方式对文件进行读写操作
打开方式要指定为ios::binary
5.2.1写文件
二进制方式写文件主要利用流对象调用成员函数write
函数原型:ostream& write(const char * buffer,int len);
参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数
cpp#include <fstream> #include <string> class Person { public: char m_Name[64]; int m_Age; }; //二进制文件 写文件 void test01() { //1、包含头文件 //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(); system("pause"); return 0; }
总结:
- 文件输出流对象可以通过write函数,以二进制方式写数据。
5.2.2读文件
二进制方式读文件主要利用流对象调用成员函数read
函数原型:istream& read(char *buffer,int len);
参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数
cpp#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(); system("pause"); return 0; }
- 文件输入流对象可以通过read函数,以二进制方式读数据
C++提高编程
- ·本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用
1模板
1.1模板的概念
模板就是建立通用的模具,大大提高复用性
例如生活中的模板
一寸照片模板:
PPT模板:
模板的特点:
- ·模板不可以直接使用,它只是一个框架
- ·模板的通用并不是万能的。
1.2函数模板
- C++另一种编程思想称为泛型编程,主要利用的技术就是模板
- C++提供两种模板机制:函数模板 和类模板
1.2.1函数模板语法
函数模板作用:
建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型 来代表。
语法:
cpptemplate<typename T> 函数声明或定义
解释:
template --- 声明创建模板
typename----表面其后面的符号是一种数据类型,可以用class代替
T ----- 通用的数据类型,名称可以替换,通常为大写字母
cpp//交换整型鹵数 void swapInt(int& a,int& b) { int temp =a; a=b; b=temp; } //交换浮点型函数 void swapDouble(double& a,double& b) { double temp = a; a=b; b=temp; } //利用模板提供通用的交换函数 template<typename T> void mySwap(T& a, T& b) { T temp = a; a=b; b=temp; } void test01() { int a=10; int b = 20; //swapInt(a,b); //利用模板实现交换 //1、自动类型推导 mySwap(a, b); //2、显示指定类型 mySwap<int>(a, b); cout << "a= "<< a<< endl; cout << "b - " << b << endl; } int main() { test01(); system("pause"); return 0; }
总结:
- 函数模板利用关键字template
- 使用函数模板有两种方式:自动类型推导、显示指定类型
- 模板的目的是为了提高复用性,将类型参数化
1.2.2函数模板注意事项
注意事项:
- 自动类型推导,必须推导出一致的数据类型T,才可以使用
- 模板必须要确定出T的数据类型,才可以使用
示例:
cpp//函数模板注意事项 //利用模板提供通用的交换函数 template<class T>//typename可以替换成class void mySwap(T& a, T& b) { T temp=a; a=b; b=temp; } //1、自动类型推导,必须推导出一致的数据类型T,才可以使用 void test01() { int a= 10; int b = 20; char c ='c'; //mySwap(a,b);//正确! //mySwap(a,c);//错误!推导不出一致的T类型 cout<<"a= "<<a<< endl; cout << "b = "<< b << endl; //2、模板必须要确定出T的数据类型,才可以使用 template<class T> Evoid func () { cout<<"func调用"<< endl; } void test02() { func<int>(); } int main() { test02(); system("pause"); return 0; }
总结:
- 使用模板时必须确定出通用数据类型T,并且能够推导出一致的类型
1.2.3函数模板案例
案例描述:
- ·利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序
- ·排序规则从大到小,排序算法为选择排序
- ·分别利用char数组 和int数组进行测试
cpp#include<iostream> using namespace std; //实现通用对数组进行排序的函数 //规则从大到小 //算法 选择 //测试 char 数组、int数组 //交换函数模板 template<class T> void mySwap(T&a, T&b) { T temp = a; a = b; b = temp; } //排序算法 template <class T> void mySort( T arr[],int len) { for (int i=0;i<len;i++) { int max = i;//认定最大值的下标 for (int j=i+1; j<len;j++) { //认定的最大值比遍历出的数值要下,说明j下标的元素才是真正的最大值 if (arr[max]<arr[j]) { max=j;//更新最大值下标 } } if(max != i) { //交换max和i元素 mySwap(arr[max],arr[i]); } } } //提供打印数组模板 template<class T> void printArray(T arr[],int len) { for (int i= 0; i<len;i++) { cout << arr[i] <<""; } cout << endl; } void test01() { //测试char数组 char charArr[]= "badcfe"; int num = sizeof (charArr) / sizeof (char); mySort (charArr, num); printArray (charArr, num); } void test02() { //测试int数组 int intArr[]={7,5, 1, 3, 9, 2, 4, 6, 8 }; int num = sizeof(intArr) / sizeof(int); mySort (intArr, num); printArray (intArr, num); } main() { test01(); test02(); system("pause"); return 0; } }