目录
1.类的定义
没有用链表而是先定义了一个结构体,再用一个类来封装,在类里定义了一个以结构体类型的vector。
struct College {
int id; // 编号,int类型
string name; // 学校名称,string类型
string address; // 地址,string类型
string province; // 省份,string类型
string create_time; // 建校时间,string类型
string website; // 网址,string类型
};
class CollegeInfo {
····
private:
// 存储高校信息的vector
vector<College> colleges_;
};
2.普遍利用auto变量和范围for语句来遍历容器
3.erase函数
删除容器内的元素
函数形式可以如下:
iterator erase (iterator position); // 删除一个元素
iterator erase (iterator first, iterator last); // 删除一个范围内的元素
因为删除元素后容器的大小会变化,在使用迭代器的时候可能会发生未知的错误,所以要return来退出循环,以防在调用迭代器的时候发生未定义的行为.
在实际使用erase的时候,不能直接删除迭代器所指向的元素,而是要把它作为容器的成员函数,删除容器内的成员.
for (auto iter = colleges_.begin(); iter != colleges_.end(); ++iter) {
if (iter->id == id) {
colleges_.erase(iter);
cout << "删除成功!" << endl;
return;
}
}
4.string类型的find方法,
形式:
size_t find(const string& str, size_t pos = 0) const noexcept;
第一个从参数是要查找的子串,第二个参数是查找的起始位置,可以不给出.
如果找到了则返回子串的起始位置,如果没有找到则返回string::npos,
npos是string类型定义的一个静态常量.
实例:
bool found = false;
for (const auto& college : colleges_) {
if (college.name.find(name) !=string::npos ) {//查找子串
found = true;
cout << "编号:" << college.id << endl;
cout << "学校名称:" << college.name << endl;
cout << "地址:" << college.address << endl;
cout << "省份:" << college.province << endl;
cout << "建校时间:" << college.create_time << endl;
cout << "网址:" << college.website << endl;
}
}
if (!found) {
cout << "未找到该高校信息!" << endl;
}
5.cin的几个与缓冲区有关的函数
(1)cin.sync();
用来清除读取缓冲区的内容,在使用之前通常先通过cin.clear()来重置状态.
注:不能清除换行符
(2)cin.clear();
清除缓冲区的输入状态,例如输入了错误的类型或者cin已经达到文件流的末尾.
注:cin.clear()只能清除错误标志,不能清除错误数据
(3)cin.ignore();
用来清空输入缓冲区的内容,可以清除换行符.
形式:
cin.ignore(int n = 1, int delim = EOF);
第一个参数是要清除的字节数,第二个参数表示一个特殊字符,遇到这个字符时停止忽略,未指定时默认为EOF,即文件结尾.
6.istringstream,字符串流
需要头文件<sstream>
从字符串中提取数据,提取规则和cin一样,用空格和换行符作为分隔.
实例:
#include <iostream>
#include <sstream>
int main() {
std::istringstream iss("123 4.56 true");
int i;
float f;
bool b;
iss >> i >> f >> b;
std::cout << "i = " << i << std::endl;
std::cout << "f = " << f << std::endl;
std::cout << "b = " << b << std::endl;
return 0;
}
i = 123
f = 4.56
b = 1
7.lambda表达式(匿名函数)
形式:
[capture list] (parameters) -> return_type { function body }
capture list是可选的,用于捕获外部变量,parameters是参数列表,return_type是返回值类型,function body是函数体.
它可以作为函数参数或返回值.
实际使用中,常常忽略lambda表达式的返回值类型,而是在函数体中定义它.
注:
"this"封闭函数默认不能直接在lambda中使用,这是因为lanbda表达式在编译过程中会被转化为函数指针,函数指针与函数有所不同,不能自动访问成员,因此在访问封闭函数"this"时,需要进行显示的捕获.
可以在声明中通过"[=]"或者'[&]"的方式进行显式捕获.,
其中'[=]'是值捕获,将当前作用域所有可见的变量拷贝到lambda表达式里,
'[&]'是引用捕获,将当前作用域里所有可见的变量作为引用拷贝到lambda表达式里.
两者都包含"this"函数
8*.sort函数
参数可以为迭代器
9.all_of函数
all_of()是STL算法库里的一个函数,用于判断一个范围内的元素是否满足某个特定条件,
形式:
bool all_of(first,last,unary_predicate);
三个参数分别表示起始位置,结束位置,和一个一元谓词函数,
通常使用迭代器.
实例:
for (const auto& college : colleges_) {
if (all_of(keywords.begin(), keywords.end(),
[&](const string& keyword) {
return check_college_match(college, keyword);//lambda表达式,引用赋予来捕获this指针以使用成员函数
})) {
found = true;
print_college_info(college);
}
}
10.文件流
(1)ofstream
标准库中的一个类,继承于ostream类,需要头文件<fstream>
形式:
ofstream ofs("test.txt", ios::out);
第一个参数为文件名,第二个参数为打开方式,所示为"写"方式,
可以通过"<<"运算符对文件进行写入
最后需要关闭文件
ofs.close();
(2)wifstream
宽字符输入流类型,用于读取宽字符的文本文件.
有特定的成员函数wcout进行宽字符输出
读取文件的数据类型也是相应的宽字符类型,例如wstring
11*.string类型和wstring类型的转化
(1)wstring_convert
wstring_convert是STL库里的一个字符串编码转换工具,需要头文件<locale>和<condecvt>,可以在不同的编码类型之间相互转换,它的泛型参数是一个condecvt类型的模板,condecvt是一个字符串编码转换类,它定义了源编码类型和目标编码类型之间的转换逻辑
实例:
#include <locale>
#include <codecvt>
#include <string>
// string to wstring
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wide = converter.from_bytes(narrow);
// wstring to string
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string narrow = converter.to_bytes(wide);
(2)*wcstombs和mbstowcs函数
12*文字编码问题
setlocale(LC_ALL, "zh_CN.UTF-8")
将全部类别的本地化环境设置为UTF-8格式
system("chcp 65001")
将当前控制台代码页改成UTF-8格式,以支持Unicode格式字符的输出,windows下默认字符编码是GBK格式
注:只对当前程序有用
std::locale::global(std::locale(""))
将当前环境的全局locale设置为默认格式,以与本地化设置相同.
fin.imbue(locale("zh_CN.UTF-8"))
设置文件流的本地化规范