一.string前言
string表示可变长字符串类型;
二.string 简介
#include<string>
char string[100] = "I LOVE CHINA";
三.初始化方式
//char string[100] = "I LOVE CHINA";
string s1;//默认初始化,此时s1="",代表什么内容也没有
string s2 = "I LOVE CHINA";//代表把I LOVE CHINA 拷贝到s2所代表的内容,但不包括末尾的\n
string s3("I LOVE CHINA");//与第二种一样,都是把所代表的内容拷贝到s3所代表的内存中
string s4 = s2;//把s2中的内容,拷贝到s4中
//单引号是字符,双引号是字符串
int num = 6;
string s5(num, 'a');//代表6个a
.四.string 对象上的操作
1.判断是否为空empty,返回的是布尔值
string s1;
if (s1.empty())
{
cout << "s1 为空" << endl;
}
2.size和length返回字节和字符数量
string s1;
cout << s1.size() << endl;
cout << s1.length() << endl;
string s2 = "I LOVE CHINA";
cout << s2.size() << endl;
cout << s2.length() << endl;
3.s[n]代表返回字符串中的第n个位置
string s1 = "I LOVE CHINA";
if (s1.size() > 4)
{
cout << s1[4] << endl;//V
}
s1[4] = 'A';
cout << s1[4] << endl;
4.sn+sn+1等价于两个字符串的链接
string s1 = "abcd";
string s2 = "cdef";
string s3 = s1 + s2;
cout << s3 << endl;
5.s1=s2,将s2的值赋给s1
string s1 = "abcd";
string s2 = "cdef";
s1 = s2;
cout << s1 << endl;
6.==两个字符串相等,必须是长度相同,且字符一样
string s1 = "abcd";
string s2 = "abcd";
if (s1 == s2)
{
cout << "s1和s2相同" << endl;
}
7.除却相同的就是!=
string s1 = "abcd";
string s2 = "abd";
if (s1 != s2)
{
cout << "s1和s2不相同" << endl;
}
8.c_str用于返回字符串中的内容指针(而且是一个常量),主要是为了兼容C,因为在C中是没有string 字符类型
string s2 = "abd";
const char* p = s2.c_str();
char str[100];
strcpy_s(str, sizeof(str), p);
cout << str << endl;
用C的数组初始化string
char str[100];
string s3(str);
9.string对象读写
string s1;
cin >> s1;
cout << s1 << endl;
10.字面值和string 相加
string s1 = "abcd";
string s2 = "cdef";
string s3 = s1 + " and " + s2;
//string s4 = "abcd" + "cdf";//在语法上是不可以的,中间必须加一个string 数据类型,两个字符串不能挨着相加
cout << s3 << endl;
11.范围for语句,遍历string中的每一个元素
string s1 = "I LOVE CHINA";
for (auto c : s1)
{
cout << c << endl;
}
12.toupper函数可以把小写字母变成大写,大写字母不变
string s1 = "i love china";
for (auto& c : s1)//加引用才能修改s1中的值
{
c = toupper(c);
}
cout << s1 << endl;
五.迭代器
1.迭代器的简介
迭代器主要用于指向容器内的某个元素(这是我们常用的),当然n【】也可以
通过迭代器我们可以访问容器中的元素,如果是string类型就是某个字符,还可以修改这些元素和字符;
2.容器的迭代类型
怎么去定义迭代器
vector<int> iv = { 100,200,300 };
vector<int>::iterator iter;//定义一个迭代器iter,定义方法是固定的要记住
3.迭代器的begin()和end()以及反向迭代器rbegin()和rend()
编辑切换为居中
添加图片注释,不超过 140 字(可选)
vector<int> iv = { 100,200,300 };
vector<int>::iterator iter;//定义一个迭代器iter,定义方法是固定的要记住
iter = iv.begin();//相当于指向容器中的第一个元素,100
iter = iv.end();//这里不是指向最后一个元素,而是指向最后一个元素的后边一个不存在的元素
//如果一个容器为空,begin()和end()返回的元素相同
4.传统的for语句遍历容器内的数据
vector<int> iv = { 100,200,300 };//定义一个容器
for (vector<int>::iterator iter = iv.begin(); iv.begin() != iv.end(); iter++)
{
cout <<*iter<< endl;
}
反向迭代器的使用方法:
vector<int> iv = { 100,200,300 };
for (vector<int> ::reverse_iterator riter = iv.rbegin(); riter != iv.rend(); riter++)
{
cout << *riter << endl;
}
5.迭代器运算符
a.*iter运算符:返回迭代器iter所指向的引用,并且不能指向end(),必须是一个有效的内容;
b.iter++和++iter:都是让迭代器指向容器中的下一个元素;
vector<int>::iterator iter = iv.begin();
iter++;
cout << *iter << endl;
c.iter--和--iter:都是让迭代器指向容器中的上一个元素
vector<int> iv = { 100,200,300 };
vector<int>::iterator iter = iv.end();
iter--;
cout << *iter << endl;
d.迭代器的相等于不相等,主要取决于迭代器指向的元素是否相同
e.迭代器和结构体的使用
struct student
{
int num;
};
int main()
{
vector<student> sv;
student myst;//实例化对象
myst.num = 100;
sv.push_back(myst);//把100推进迭代器中
vector<student>::iterator iter;
iter = sv.begin();
cout << (*iter).num << endl;
cout << iter->num << endl;//两种使用方法都可以
6.普通的迭代器是可以对容器中的数据进行读写操作,但是带cosnt的常量迭代器只能进行读数据的操作
vector<int> sv = { 100,200,300 };
vector<int>::const_iterator iter;
for (iter = sv.begin(); sv.begin() != sv.end(); iter++)
{
cout << *iter << endl;//这里这个迭代器的作用相当于一个常量指针
}
.不加const可以对容器中的内容进行修改
vector<int> sv = { 100,200,300 };
vector<int>::iterator iter;
for (iter = sv.begin(); sv.begin() != sv.end(); iter++)
{
*iter = 4;
cout << *iter << endl;//这里这个迭代器的作用相当于一个常量指针
}
7.cbegin()和cend()返回的都是常量迭代器,都是可以读数据,但是不能改
vector<int> sv = { 100,200,300 };
vector<int>::iterator iter;
for (auto iter = sv.cbegin(); iter != sv.cend(); iter++)
{
cout << *iter << endl;
}
8.迭代器失效问题
vector<int> sv = { 100,200,300 };
for (auto beg = sv.begin(),end=sv.end(); beg!= end; beg++)
{
sv.push_back(888);//这样往容器里面加元素,就会导致迭代器失效
cout << *beg << endl;
}
.任何在for循环中加容器中元素的操作都要慎重,因为这样很容易导致迭代器的失效,代表,这些指针无法代表容器中 的元素。
解决方法:
vector<int> sv = { 100,200,300 };
for (auto beg = sv.begin(),end=sv.end(); beg!= end; beg++)
{
sv.push_back(888);
break;
}
for (auto beg = sv.begin(), end = sv.end(); beg != end; beg++)
{
//sv.push_back(888);//这样往容器里面加元素,就会导致迭代器失效
cout << *beg << endl;
}
9.灾难程序演示
a.
vector<int>vecvalue = { 100,200,300 };
auto beg = vecvalue.begin();
auto end = vecvalue.end();
while (beg != end)
{
//如果我们要插入元素,就要用到insert函数
vecvalue.insert(beg,88888);//函数第一个元素是插入位置,第二个是插入数据
break;//为了防止迭代器失效,这里需要直接跳出循环
cout << *beg << endl;
beg++;
}
beg = vecvalue.begin();
end = vecvalue.end();
while (beg != end)
{
cout << *beg << endl;
beg++;
}
b.在迭代器中插入一串数字的方法
vector<int>vecvalue = { 100,200,300 };
auto beg = vecvalue.begin();
//auto end = vecvalue.end();
int icout = 0;
while (beg != vecvalue.end())//每次更新防止迭代失效
{
beg = vecvalue.insert(beg, icout+80);
icout++;
if (icout > 10)
break;
beg++;
}
beg = vecvalue.begin();
auto end = vecvalue.end();
while (beg != end)
{
cout << *beg << endl;
beg++;
}
c.灾难程序演示,怎么安全释放容器中的元素
vector<int> iv = { 100,200,300,40 };
for (auto beg = iv.begin(); beg != iv.end(); beg++)
{
iv.erase(beg);//eraes移除beg位置上的元素,并且返回到下一个位置
}//错误案例,会导致迭代器失效
.正确方法:
vector<int> iv = { 100,200,300,40 };
vector<int>::iterator iter = iv.begin();
while (iter != iv.end())
{
iter = iv.erase(iter);
}
更加粗暴的方法且有用:
vector<int> iv = { 100,200,300,40 };
while (!iv.empty())
{
auto iter = iv.begin();
iv.erase(iter);
}
10.用迭代器遍历string类型数据
string 虽然不是容器,但是也可以用迭代器遍历
string str = "i love china";
for (auto iter = str.begin(); iter != str.end(); iter++)
{
*iter = toupper(*iter);
}
cout << str << endl;
11.vector容器常用操作
编辑切换为居中
添加图片注释,不超过 140 字(可选)
struct conf {
char itemname[40];
char itemcontent[100];
};
//char *希望返回一个字符串
char* getinfo(vector<conf*>& conlist,const char* pitem)
{
for (auto pos = conlist.begin(); pos != conlist.end(); ++pos)
{
//_stricmp_字符串比较
if(_stricmp((*pos)->itemname,pitem)==0)
{
return (*pos)->itemcontent;//根据名字来查内容
};
}
return nullptr;
}
int main()
{
conf* pconf1 = new conf;
strcpy_s(pconf1->itemname, sizeof(pconf1->itemname), "Servername");
strcpy_s(pconf1->itemcontent, sizeof(pconf1->itemcontent), "1区");
conf* pconf2 = new conf;
strcpy_s(pconf2->itemname, sizeof(pconf2->itemname), "ServerID");
strcpy_s(pconf2->itemcontent, sizeof(pconf2->itemcontent), "11111");
vector<conf*> conlist;//容器中放的结构体
conlist.push_back(pconf1);
conlist.push_back(pconf2);//容器中放入以上两个内容
char* p_temp = getinfo(conlist, "Servername");
if (p_temp != nullptr)
{
cout << p_temp << endl;
}
//new手动开配手动释放
std::vector<conf*>::iterator pos;
for (pos = conlist.begin(); pos != conlist.end(); pos++)
{
delete(*pos);//这里是蓝色部分,并没有破坏迭代器,至少删除了额外的内存
}
conlist.clear();//清空迭代器
return 0;
}