一、文件操作
1.1 I/O 流概念和流类库的概念
程序输入输出
输入:应用程序将数据导出的操作
输出:从外部获取数据到程序内部的操作
C++输入和输出分为三类
1、对系统指定的标准设备的输入和输出, 即标准I/O
2、以外存磁盘文件为对象进行的输入和输出,即文件I/O
3、对内存中指定的空间进行输入和输出,通常指定一个字符数据作为存储空间,字符串IO
C++的IO对c的发展,类型安全,可拓展性强。
C++在输入输出时,对数据类型进行严格检查
C++ I/O可扩展
C++通过IO类库实现丰富的IO功能,要比printf和scanf更加强大,缺点就是C++中的IO系统变得更复杂。
1.2 iostream
iostream:标准输入输出流类,由三个部分组成 i o s
cin: 标准输入流类 键盘 istream stdin
cout: 标准输出流类 屏幕 ostream stdout
cerr: 标准错误流类 屏幕 ostream stderr
clog: 标准错误流类 屏幕 ostream stderr
输入流函数,除了调用”>>“,还有get() , getline()
get函数时cin输入流对象的成员函数,有三种形式:无参,1个参数,三个参数
无参:cin.get();读取一个字符(包括空白字符),函数的返回值是读入的字符。和C语言中的getchar()功能相同
有一个参数:cin.get(ch)从输入流中读取一个字符,赋给字符变量ch,
有三个参数:cin.get(字符数组/字符指针,字符个数n,终止字符),作用,从输入流中读取n-1个字符赋给指定的字符数组,如果提前遇到终止字符则提前结束读取
getline() 作用是从输入流中读取一行字符,用法与带三个参数的get()一样
输出流除了以上重写“<<”,还有 put(), write(),flush()
put() 函数可以向控制台输出单个字符
write() 函数可以输出字符数组
flush() 函数是有缓冲区的,在向缓冲区写入数据时,数据不会立即写入目标,而是先写入缓冲区,满足下列条件之一时,缓冲区将进行刷新,将数据写人目标。
1)遇到换行,如endl
2)流对象离开作用域被析构时
3)当进行输入操作时,要求从cin输入时,cout会被刷新
4)流缓存满时
5)刷新显示的流缓存
输出流的错误处理函数:
good():判断当前流是否处于正常状态
bad():流是否发生致命错误
fail():在最后一次操作失败时返回true
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
char ch;
char buf[32] = {
0};
/* cout<<ch<<endl;
ch = cin.get();
cout<<ch<<endl;
cin.get(ch);
cout<<ch<<endl;
cin.get(buf,10); //获取字符串,最多10个字节
cout<<buf<<endl;
cin.getline(buf,10); //获取一行数据,最多10个字节
cout<<buf<<endl;
cin.ignore(5); //忽略前5个字节
cin>>buf;
cout<<buf<<endl;
ch = cin.peek(); //获取一个字符,同时将字符串留在缓冲区
cout<<ch<<endl;
cin>>buf;
cout<<buf<<endl;
cin>>buf;
cout<<buf<<endl;*/
cin>>ch;
cin.putback(ch); //把ch放回缓冲区
cin>>buf;
cout<<buf<<endl;
return 0;
}
#include <iostream>
#include <iomanip>
using namespace std;
int main(int argc, char const *argv[])
{
#if 0
int num = 1000;
int count = 2000;
cout<<oct<<num<<endl; //以8进制输出
cout<<count<<endl; //这里会继续表示8进制的数据
cout<<dec<<num<<endl; //以10进制输出
cout<<hex<<num<<endl; //以16进制输出
cout<<setbase(8)<<num<<endl; //以8进制输出
cout<<setbase(16)<<num<<endl; //以16进制输出
double PI = 222.0000 / 9.00000;
cout<<PI<<endl;
cout<<setprecision(15)<<PI<<endl; //设置输出宽度为15位
cout<<setprecision(15)<<setiosflags(ios::scientific)<<PI<<endl; //科学计数法
const char *s = "helloworldwed";
cout<<setw(15)<<setfill('*')<<s<<endl; //用*填充
#endif
//使用成员函数
int num = 1000;
cout.unsetf(ios::dec); //结束10进制的格式输出
cout.setf(ios::oct); //设置8进制格式输出
cout<<num<<endl;
cout.unsetf(ios::oct); //结束8进制的格式输出
cout.setf(ios::hex); //设置16进制格式输出
cout<<num<<endl;
double PI = 222.0000 / 9.00000;
cout.precision(5);
cout<<PI<<endl;
cout.setf(ios::scientific);
cout<<PI<<endl;
const char *s = "helloworld";
cout.width(15);
cout.fill('*');
cout<<s<<endl;
return 0;
}
文件的读写操作
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main(int argc, char const *argv[])
{
#if 0
//写
char buf[32] = "helloworld";
ofstream ofs; //创建输出流对象(写文件)
ofs.open("./1.text",ios::out); //使用默认参数
ofs<<buf; //使用输出运算符将buf写入文件
ofs.close();
//读
memset(buf,0,sizeof(buf));
ifstream ifs("./1.text"); //创建输入流对象(读文件),通过构造函数,打开文件
ifs >> buf;
cout<<buf<<endl;
ifs.close();
#endif
char buf[32] = "helloworld";
char ch;
memset(buf,0,sizeof(buf));
fstream fs;
fs.open("hello.c",ios::in); //输入的方式打开
while(ch = fs.get() != EOF)
{
cout<<ch;
}
cout<<endl;
fs.close();
return 0;
}
二、STL
2.1 什么是STL
STL是标准模板库,由惠普公司开发,现在主要出现在C++中
STL从广义上分:容器,算法,迭代器,容器和算法之间是通过迭代器进行无缝连接,在STL中,几乎所有的代码都采用模板类和模板函数,这个相比传统的类来讲,重要性大大提高,STL标准模板库,C++占比高达80%以上
特点:1.将数据结构和算法分离
2.不需要关心具体的实现过程,只要熟练使用STL就OK
3.STL具有高度的重用性,高性能,高移植性,跨平台性。
2.2 string
1)是STL字符串类型,通常用来表达字符串
2)string和char 的区别
1.string是一个类,char是一个指向字符的指针。
2.string封装了char*,管理这个字符串,是一个char*的容器。
3.string不需要考虑内存释放和申请。
4.提供一系列字符串的操作。
find,copy,erase,replace,insert…
2.3 STL六大组件
1.六大组件:容器,算法,迭代器,仿真函数,适配器,空间配置器
2.容器:各种数据结构
3.算法:增删改查
4.迭代器:是容器和算法的融合剂,共有5种类型,从实现角度讲是一种指针运算符的重载 operator*
5.仿函数:类似函数,外表使用方法类似函数
6.适配器:一种用来修饰容器或者仿函数或者迭代器的东西
7.空间配置器:负责空间的配置和管理,从实现角度看,实现了一个动态空间的配置,空间的管理,空间的释放。
容器:
2.4 C++标准库的优点
1.成本:已经作为标准提供了,不需要再投入人力物力去开发
2.质量:标准库经过严格测试,正确性有保障
3.效率:较高
4.良好的编程规范:
2.5 string
string不是STL容器,但是他和STL有许多类似的操作,因此放在这边一起介绍
using std::string 或者 using namespace std;
#include <iostream>
#include <cstring>
using namespace std;
int main(int argc, char const *argv[])
{
/*
string s1;
string s2("helloworld");
string s3(10,'a'); //用10个a来初始化
string s4(s2); //拷贝构造函数
cout<<s1<<endl;
cout<<s2<<endl;
cout<<s3<<endl;
cout<<s4<<endl;
s1 += "helloworld";
cout<<s1<<endl;
s1 = s1 + s3;
cout<<s1<<endl;
string s("helloworld");
cout<<s[1]<<endl; //重载了下标运算符
s[1] = 'x';
cout<<s[1]<<endl; //重载了下标运算符
try
{
cout<<s.at(10)<<endl;
}
catch(const std::exception& e)
{
cout << e.what() << endl;;
}
char buf[32] = {0};
string s5("helloworld");
s5.copy(buf,5,2); //第三个参数是默认参数,拷贝的位置默认是0
cout<<buf<<endl;
*/
/*
//string 长度
string s("hellowprld");
cout<<s.length()<<endl;
if(s.empty())
{
cout<<"字符串为空"<<endl;
}
else
{
cout<<"字符串不是空"<<endl;
}
//string 字符串赋值
string s1("hellowprld");
s1 = "hello"; //重载了等号,会覆盖到原来内容
cout<<s1<<endl;
const char *ss = "this is test";
s1.assign(ss); //把ss赋值给s1;
cout<<s1<<endl;
s1.assign(ss,7); //把前7个赋值给s1
cout<<s1<<endl;
//string连接
string s1("helloworld");
string s2("1234567890");
s1 += "123";
cout<<s1<<endl;
//cout<<s1<<endl;
const char *s = "hahah";
s1.append(s,2); //把s的前两个字节接到s1后面
cout<<s1<<endl;
s1.append(s2);
cout<<s1<<endl;
s1.append(s2,4,2); //从数组下标4开始,往后数两个字节
cout<<s1<<endl;
s1.append(10,'x');
cout<<s1<<endl;
*/
//string比较
/*
string s1("hellowprld");
string s2("hellobody");
const char *s = "hellogirl";
if(s1.compare(s2) > 0)
{
cout<<"s1 > s2"<<endl;
}
if(s1.compare(s) > 0)
{
cout<<"s1 > s"<<endl;
}
//string 子串
cout<<s1.substr(5,4)<<endl;*/
//string的查找
/* string s3("helloworldhelloworldhelloworldhelloworldhelloworldhelloworld");
while(s3.find("world") != -1)
{
s3.replace(s3.find("world"),5,"ooooo");
}
cout<<s3<<endl;
*/
//string的插入和删除
string s1("helloworld");
string s2("12345");
s1.insert(0,"this is ");
cout<<s1<<endl;
s1.insert(10,s2);
cout<<s1<<endl;
s1.insert(10,5,'x');
cout<<s1<<endl;
s1.erase(0,20); //删除
cout<<s1<<endl;
return 0;
}
2.6 vector
vector是将元素放置在一个动态数组中加以管理的容器
vector是可以随机存取元素(支持索引直接存取,用[]直接存取,也可以使用at()的方式)
vector尾部添加或者移除元素非常快速,但是在中部或者头部掺入元素比较费劲。
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char const *argv[])
{
int data[10] = {
1,2,3,4,5,6,7,8,9,10};
vector<int> v1; //创建数组对象
vector<int> v2(data,data + 10); //左闭右开
vector<int> v3(10,1);
v1.resize(10); //扩充容量
for(int i = 0; i < 10; i++)
{
v1[i] = i; //重载下标运算符
}
for(int i = 0; i < v2.size(); i++)
{
cout<<v2.at(i)<<" "; //
}
cout<<endl;
//正向迭代器
for(vector<int>::iterator it = v3.begin(); it != v3.end(); it = it + 2)
{
cout<<*it<<" ";
}
cout<<endl;
//反向迭代器
for(vector<int>::reverse_iterator rit = v2.rbegin(); rit != v2.rend(); rit++)
{
cout<<*rit<<" ";
}
cout<<endl;
//只读迭代器
for(vector<int>::const_iterator cit = v2.begin(); cit != v2.end(); cit++)
{
cout<<*cit<<" ";
}
cout<<endl;
return 0;
}
2.6.1 vector的插入和删除
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int main(int argc, char const *argv[])
{
const char *str = "this is";
const char *s = "helloworld";
vector<char> v(s,s + strlen(s));
//正向迭代器
for(vector<char>::iterator it = v.begin(); it != v.end(); it++)
{
cout<<*it<<" ";
}
cout<<endl;
v.insert(v.begin(),'X');
for(vector<char>::iterator it = v.begin(); it != v.end(); it++)
{
cout<<*it<<" ";
}
cout<<endl;
v.insert(v.end(),5,'X');
v.insert(v.begin(),'X');
for(vector<char>::iterator it = v.begin(); it != v.end(); it++)
{
cout<<*it<<" ";
}
cout<<endl;
v.insert(v.begin(),str,str+strlen(str));
for(vector<char>::iterator it = v.begin(); it != v.end(); it++)
{
cout<<*it<<" ";
}
cout<<endl;
v.erase(v.end() - 5,v.end());
for(vector<char>::iterator it = v.begin(); it != v.end(); it++)
{
cout<<*it<<" ";
}
cout<<endl;
v.erase(v.begin() + 8);
for(vector<char>::iterator it = v.begin(); it != v.end(); it++)
{
cout<<*it<<" ";
}
cout<<endl;
return 0;
}
2.7 deque
接口:
char(); //移除所有元素
erase(beg,end); //左闭右开的删除
erase(pos); //删除某个位置的数据
#include <iostream>
#include <deque>
using namespace std;
int main(int argc, char const *argv[])
{
int data[10] = {
2,4,1,3,5,3,1,7,3,3};
deque<int> d(data,data + 10);
for(deque<int>::iterator it = d.begin(); it != d.end();)
{
if(*it == 3)
{
d.erase(it);
}
else
{
it++;
}
}
cout<<endl;
for(deque<int>::iterator it = d.begin(); it != d.end(); it++)
{
cout<<*it<<" ";
}
cout<<endl;
return 0;
}