string,vector和array(C++ Primer读书笔记)
string
string是标准库类型,使用时需要包涵头文件,使用using声明。
include <string>
using std::string;
1.定义和初始化
string s1;
string s2(s1);
string s2 = s1;
string s3("value");
string s3 = "value";
string s4(n, 'c');//把s4初始化为连续n个字符c组成的串
2.操作
getline(is, s);//从is中读取一行附给s,返回is。例如getline(cin,s);
s.empty(); //s为空返回true,否则返回false
s.size(); //返回s中字符个数
还可以对string使用[],+,=,==,!=,<,>,<=,>=(字典序比较)等运算符。
用cin读取string对象时,会忽略前面的空白,读到正真的字符到空白为止。
getline注意一下,它读入一行,如果想读入的字符串有空格就不能直接用cin读入,这时可以使用getline。getline会读入换行符,但是读入的字符串并不包含回车符。
3.string::size_type类型
size函数的返回值是string::size_type类型。
可以通过auto(auto len=line.size();
)或decltype(decltype(s.size()) cnt=0
)
注意:"Hello"+"world";
这个语句是错的,因为字符串字面值不是string类型,不能直接想加。但是”Hello”+string是可以的。
4.cctype头文件中的函数
isalnum(c); //当c是字母或数字时为真
isalpha(c); //字母
isdigit(c); //数字
islower(c); //小写字母
isupper(c); //大写字母
ispunch(c); //标点符号
isspace(c); //空白
tolower(c); //大写变小写
toupper(c); //小写变大写
5.范围for(range for)
for (auto c : str)
cout << c << endl;
一段测试代码。
#include <iostream>
#include <string>
using namespace std; int main()
{
string str1, str2, str;
cout << "cin读入字符串只能读到空格~" << endl;
cin >> str1;
cout << str1 << endl;
cin.sync(); //清空输入缓冲区
cout << "getline可以读入一行~" << endl;
getline(cin, str2);
cout << str2 << endl;
//-----size()函数返回string::size_type类型,可以用auto或decltype来声明
cout << "用for循环遍历str2" << endl;
for (string::size_type i = 0; i < str2.size(); i++)
{
cout << str2[i] << " ";
}
cout << endl;
//-----string对象可以直接相加
cout << "string对象可以直接相加,比如~" << endl;
str = str1 + str2;
cout << str << endl;
//----范围for
cout << "用范围for遍历string" << endl;
for (auto &ch : str)
{
//这里也许需要注意一下,变量必须是在for内声明,比如char ch; for(ch : str)这样是错的编译不会通过。
ch = toupper(ch);
}
cout << str << endl;
return 0;
}
vector
vector是类模板。
用法样例:vector<int> ivec; vector<vecrot<string>> file;
过去(C++ 11之前)定义必须写成 vector<vecrot<string> /*这里是一个空格*/> file;
1.初始化
vector<T> v1; //一个空的vector对象
vector<T> v2(v1);
vector<T> v2 = v1;
vector<T> v3(n, val);
vector<T> v4(n); //n个元素,默认初始值
vector<T> v5{a, b, c...};
vector<T> v5={a, b, c...};
2.操作
v.pash_back(val);//把元素val添加到vector的尾端。如果vector<int> v(n),那么v.push_back()是从第n+1个数开始加的,即v[n]
v.empty();
v.size();
v[n];
v1 == v2;//v1和v2元素数量相等,且每一个值都相同
v1 != v2;
<, <=, >, >=
3.迭代器
begin成员负责返回指向第一个元素的迭代器
end成员负责返回指向容器“尾元素的下一位置”的迭代器,没有实际意义,仅起标记作用,常称为尾后迭代器。
有关push_back();
vector<int> vec(10);
for(vector<int>::size_type i = 0; i != vec.size(); i++){
vec.push_back(i);
}
这是死循环,因为vec.size()随循环边长~同理,范围for中也不要加入尝试添加元素。同时可能改变vector对象容量的操作,会使该对象迭代器失效。
vector初始化小测试,orz我的编译器不支持C++11
#include <iostream>
#include <string>
#include <vector>
using namespace std; void print(vector<int> vec)
{
for (vector<int>::iterator ip = vec.begin(); ip != vec.end(); ip++)
{
cout << *ip << " ";
}
cout << endl;
} int main()
{
vector<int> vec1(10);
print(vec1);
vector<int> vec2(10, 8);
print(vec2);
vector<int> vec3{10, 8};
print(vec3);
vector<int> vec4(vec3);
vec4.push_back(6);
print(vec4); return 0;
}
输出结果为
0 0 0 0 0 0 0 0 0 0
8 8 8 8 8 8 8 8 8 8
10 8
10 8 6
练习题3.17(很好奇为什么有push_back没有删除,于是搜到了erase,试着用了一下。
#include <iostream>
#include <string>
#include <vector>
using namespace std; int main()
{
vector<string> vec;
string str;
while (cin >> str)
{
vec.push_back(str);
}
for (vector<string>::iterator ip = vec.begin(); ip != vec.end(); ip++)
{
if (*ip == "yi")
{
vec.erase(ip);
}
}
for (vector<string>::iterator ip = vec.begin(); ip != vec.end(); ip++)
{
for (char &ch : *ip)
{
ch = toupper(ch);
}
cout << *ip << " ";
cout << endl;
} return 0;
}
输入:
yi shan yi shan liang jing jing
输出:
SHAN
SHAN
LIANG
JING
JING
”后来才发现有问题,懒得改了,因为在循环中删除元素,导致迭代器错误。比如输入yi yi er yi yi er 就会输出YI ER YI ER 循环中改成if (*ip == "yi") { vec.erase(ip); --ip; }
会好吧。
练习题3.26
值得注意,因为窝自己就写成了mid = (beg + end) / 2;
结果出错。因为并没有重载iterator之间的加法。
写成mid = beg + (end - beg) / 2;
到做题时有人也这么写,我嫌麻烦从来都是(l + r) >> 2
,突然意识到也许他们是防止数据太大溢出(捂脸
数组
数组在c语言都学过的就一眼带过了。
数组的下标是size_t类型(一直以为unsigned int啊喂)在cstddef头文件中定义。
指针也是迭代器。
通过函数begin()和end()返回指向数组首元素和尾元素的下一位置的指针。参数为数组。
ptrdiff_t n = end(arr) - begin(arr); //n即为arr中的元素
ptrdiff_t为标准库类型,定义在cstddef头文件中。它的空间足够大,能表示数组中任意两个指针之间的距离。
#include <iostream>
using namespace std; int main() {
char arr[10];
cin >> arr;
for (auto i = begin(arr); i != end(arr); i++){
cout << *i << " ";
}
cout << "there are " << end(arr) - begin(arr) << " elements";
return 0;
}
输入:1234567
输出:1 2 3 4 5 6 7 there are 10 elements
可以用数组初始化vector对象。
例:
int int_arr[] = {0, 1, 2, 3, 4, 5};
vector<int> ivec(begin(int_arr), end_arr(int_arr));
vector<int> subVec(int_arr + 1, int_arr + 4);
通过函数c_str();可以将string返回一个字符数组(C风格字符串)。返回值为const char*类型。如果后续一直想用该数组,最好拷贝一份。
用范围for遍历二维数组
#include <iostream>
using namespace std; int main() {
int arr[][3] = {{1, 2, 3}, {3, 4, 5}, {5, 6, 7}, {}, {9, 7, 8}};
for (const auto &row : arr){
for (auto col : row)
cout << col << " ";
cout << endl;
}
return 0;
}
如果row不加&的话会编译出错(error: ‘begin’ was not declared in this scope for (auto col : row)),原因是不声明为引用类型,row数组会自动转化为指针int *。
类性别名简化多维数组的指针
using int_array = int[4];
typedef int int_array[4];//这两个语句等价,将类型“4个整数组成的数组”命名为int_array。
string,vector和array(C++ Primer读书笔记)的更多相关文章
- c++ primer 读书笔记
顺序容器:为程序提供控制元素存储和访问顺序的能力,这种顺序与元素加入到容器时的位置相对应,而与元素值无关. 另外还有根据关键字的值来存储元素的容器:有序.无序关联容器. 另外STL还有三种容器适配器, ...
- Namespace, string, vector and array
1. Headers should not include using declaration Code inside headers ordinarily should not include us ...
- Key Technologies Primer 读书笔记,翻译 --- Struct 学习 1
原文链接:https://struts.apache.org/primer.html 本来想写成读书笔记的,结果还是变成翻译,谨作记录,学习. 1.HTML -- 见我前面文章 2.Interne ...
- c++ primer读书笔记之c++11(二)
1 新的STL模板类型,std::initializer_list<T> c++11添加了initializer_list模板类型,用于提供参数是同类型情况的可变长度的参数传递机制,头文件 ...
- c++ primer读书笔记之c++11(一)
1 新的关键词nullptr c++11引入新的关键词nullptr,用于表示空指针,用于替换之前c提供的NULL(最初NULL是定义在stdlib中的宏定义,通常是0). 2 新的别名定义机制 al ...
- C++ Primer 练习7.32(C++ Primer读书笔记)
第七章 类 练习7.32 定义你自己的Screen和Window_mgr,其中clear是Window_mgr的成员,是Screen的友元. 由于Window_mgr中含有Screen对象,所以在W ...
- 函数(C++ Primer读书笔记)
C++ Primer 第五版课后题 练习6.32 :下面的函数合法吗?如果合法,说明其功能:如果不合法,修改其中的错误并解释原因. #include <iostream> using na ...
- C++ primer读书笔记 chapter3 标准库类型
除第二章介绍的是C++的基本类型,本章将大致介绍一下C++定义的内容丰富的抽象数据库类型标准库.着重介绍一下sting.vector和bitset. 3.2标准库string类型 1.string类型 ...
- C++ Primer 读书笔记: 第9章 顺序容器
第9章 顺序容器 引: 顺序容器: vector 支持快速随机访问 list 支持快速插入/删除 deque 双端队列 顺序容器适配器: stack 后进先出栈 queue 先进先出队列 priori ...
随机推荐
- STL set_difference set_intersection set_union 操作
以下是STL algorithm的几个函数,使用的条件是有序容器,所以 vector在被sort了之后是可以使用的,set也是可以使用的. set_difference 这个是求得在第一个容器中有,第 ...
- 制作按钮(Button)
按钮的核心作用 1.按钮能接收单击并触发响应事件. 2.按钮被单击时能同时触发多个响应事件. 3.按钮可以有普通.悬停.单击.禁用等多个状态的不同表现. 4.广泛的说,按钮的核心在于接收事件,任何可以 ...
- python中数据的保存
1.将list中的数据写入到excel文件中 利用python包numpy(实现方式应该有许多种,这里只是记录成功实现的一种)中的savetxt 局限性:要保存的list可以为[1,2,3,4,5]这 ...
- 使用ssh公钥实现免密码登录
使用ssh公钥实现免密码登录 ssh 无密码登录要使用公钥与私钥.linux下可以用用ssh-keygen生成公钥/私钥对,下面我以CentOS为例. 有机器A(10.207.160.34),B(10 ...
- 浏览我的php网页时,出现的都是网页的代码
添加php模块 ,在apache/conf/httpd.conf,如果是windows下的话,添加如下代码,具体路径你根据具体情况设置#BEGIN PHP INSTALLER EDITS - REMO ...
- HDU 2985 Another lottery(坑题)
点我看题目 题意 : 有n个人,每个人可以玩m轮,每一轮中每个参与者都有cj张票,第 i 轮的奖金是2的i次方,问你每个人所能赢得最多的奖金的概率是多少. 思路 : 这个题比较坑啊,其实不用去算前几轮 ...
- ZOJ 3490 String Successor
点我看题目 题意 : 给你一个字符串,让你按照给定规则进行处理. 如果字符串里有字母或者是数字就忽略非字符数字,如果没有,就让最右边的那个字符+1. 增量都是从最右边的字母或者数字开始的. 增加一个数 ...
- [Gauss]POJ1681 Painter's Problem
和POJ1222(分析)完全相同 题意也类似, 可以涂自己以及上下左右五个位置的颜色 问几次能全部涂色 不能输出inf 01方程组 用异或来求解就好了 ][]; // 增广矩阵 ]; // 解 ]; ...
- 你所不知道的string.xml
String 能被应用程序或者其他资源文件(比如layout XML)引用的单个字符串. 注意:字符串是简单类型资源,是用名称(name)(而非XML文件名)来直接引用的.因此,在一个XML文件里,可 ...
- cat主要有三大功能
cat主要有三大功能:1.一次显示整个文件.$ cat filename2.从键盘创建一个文件.$ cat > filename 只能创建新文件,不能编辑已有文件.3.将几个文件合并为一 ...