C++ 学习日记
文件操作
程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放
通过文件可以将数据持久化
C++中对文件操作需要包含头文件<fstream>
文件类型分为两种:
1.文本文件:文件以文本的ASCII码形式存储在计算机中
2.二进制文件:文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们
操作文件的三大类:
1. ofstream:写操作
2. ifstream:读操作
3. fstream:读写操作
5.1文本文件
5.1.1写文件
写文件步骤如下:
1. 包含头文件
#include <fstream>
2. 创建流对象
ofstream ofs;
3. 打开文件
ofs.open("文件路径",打开方式);
4. 写数据
ofs <<“写入的数据";
5. 关闭文件
ofs.close();
文件打开方式
注意:文件打开方式可以配合使用,利用 | 操作符
例如:用二进制方式写文件 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();system("pause");return 0; }
总结:
- 文件操作必须包含头文件fstream
- 读文件可以利用ofstream,或者fstream类
- 打开文件时候需要指定操作文件的路径,以及打开方式
- 利用<<可以向文件中写数据
- 操作完毕,要关闭文件
5.1.2读文件
读文件与写文件步骤相似,但是读取方式相对于比较多
读文件步骤如下:
1. 包含头文件
#include <fstream>
2. 创建流对象
ifstream ifs;
3.打开文件并判断文件是否打开成功
ifs.open("文件路径"打开方式):
4. 读数据
四种方式读取
5. 关闭文件
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 //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是读写的字节数#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是读写的字节数
#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函数模板语法
函数模板作用:
建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。
语法:template<typename T> 函数声明或定义
解释:
template --- 声明创建模板
typename----表面其后面的符号是一种数据类型,可以用class代替
T ----- 通用的数据类型,名称可以替换,通常为大写字母//交换整型鹵数 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的数据类型,才可以使用
示例://函数模板注意事项//利用模板提供通用的交换函数 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数组进行测试
#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; } }