您的位置:首页 > 编程语言 > C语言/C++

20170114C++阶段班04_STL_01string

2017-01-14 18:19 519 查看

STL:



以应用为主,不会涉及太多原理!
1:所有使用的C语言的标准库都是由编译器提供的,编译器会根据C语言标准来提供,要做编译器,就必须提供应有的库(string.h等),里面的函数功能也必须一样,同样的库,不同编译器实现的方法、版本、路径等都可能不同,编译器更新也可能会改变这些,但是这些都是提供的功能接口,如何实现的我们可以不管。

    C语言提供的是一些函数,而C++提供的是一些类!使用可变长字符串类string,包含#include <string>,string.h是C语言的一些操作。

2:字符串有两种表现形式
    1:常量区里面,拿一个指针指向他。
    2:数组,在栈里面对字符串进行存储。
    注意:无论哪种,他的长度都是不可变的!
  C++里面的std::string类,是可变长字符串类。必须包含#include<string>
3:using std::string,开放命名空间一部分。

#include <iostream>
//#include <string.h>		//C语言的  支付穿操作函数头文件
//#include <cstring>		//C语言里面符合C++标准的字符串操作函数
#include <string>		//C++ STL 可变长字符串

int main()
{
std::string str = "0123456789";
std::cout << str << std::endl;
return 0;
}


string类其实是一个过度类,真正实现的地方在basic_string类里面(basic_string在#include<xstring>里面),
4:模版是一个自推导类型。模版编程(又名泛型编程),不仅仅能帮我们进行类型的推导,还可以帮我们实现方法的生成。

eg:
template<typename T>//代表一个类型,这就是泛型编程
void Swap(T& lhs, T& rhs)
{
T temp = lhs;
lhs = rhs;
rhs = temp;
}
int main()
{
//	string str = "0123456789";
//	std::cout << str << std::endl;
int num1 = 10, num2 = 50;
double d1 = 1.02, d2 = 10.24;
Swap(num1, num2);
Swap(d1, d2);			//自动匹配类型,float,char,类(class)等都可以。
std::cout << num1 << "   " << num2 << std::endl;
std::cout << d1 << "   " << d2 << std::endl;
return 0;
}


    泛型他会更具传入的参数自动判断类型,他会自动更具类型生成函数,上面两次调用这个函数,实际上是自动生成相对应的两个函数,反汇编下可以看到内存地址不一样。类似于重载,但是是有区别的。泛型类似于C里面的void*。
    泛型(模版)对类而言,里面必须使用默认生成有的运算符才可以,尤其是针对类的时候,否则可能会出错。

5:wstring和string:
    传参数分别为char_t,wchar_t,最终都是在basic_string里面来实现的。wstring和string只是过渡类,为了区分!
    区别:wstring是宽字节的,string是窄字节的。宽字节是可以存放unicode编码的,二者只是字节上的不同,而不是编码上的不同。
6:构造函数:
以下来源于:http://www.cplusplus.com/,C++98标准。

default (1)

explicit basic_string (const allocator_type& alloc = allocator_type());

copy (2)

basic_string (const basic_string& str);

substring (3)

basic_string (const basic_string& str, size_type pos, size_type len = npos,

const allocator_type& alloc = allocator_type());

from c-string (4)

basic_string (const charT* s, const allocator_type& alloc = allocator_type());

from sequence (5)

basic_string (const charT* s, size_type n,

const allocator_type& alloc = allocator_type());

fill (6)

basic_string (size_type n, charT c,

const allocator_type& alloc = allocator_type());

range (7)

template <class InputIterator>

basic_string (InputIterator first, InputIterator last,

const allocator_type& alloc = allocator_type());

测试:
std::string s0 ("Initial string");
std::string s1;					//默认的构造函数
std::string s2 (s0);					//拷贝构造
std::string s3 (s0, 8, 3);				//取类对象字串(第三个参数默认为std::string::npos,即-1(0xFFFFFFFF),最大值)。
std::string s4 ("A character sequence", 6);		//取前面6个,这个语义与其他有差别,需注意!并不是从下标6往后面取,而是取前六个。
std::string s5 ("Another character sequence");	//取全部字符串
std::string s6 (10, 'x');				//加入10个字符
std::string s7a (10, 42);				//加入10个ascii码为42的字符
std::string s7b (s0.begin(), s0.begin()+7);		//取s0前七个。传入的参数是迭代器


以上来源于:http://www.cplusplus.com/,C++98标准。
    string类所有下标范围默认都是半闭半开,上面s3取的是下标8,9,10三个。

    另外,对s3 ,还可以为 std::string str("0123456789",3,3);//会调用转换构造函数(s5),产生了临时对象的,然后再调用s3用的构造函数。
basic_string里面提供了很多函数,包括,字符串操作,流运算符等。
7:其他方法函数:
string.begin;,string.end;,string.rebegin;,string.rend;,string.cbegin;,string.cend;,string.crbegin;,string.crend;
    //以上函数返回值都是迭代器Iterators。在上面s7b用的就是这个。Iterators是迭代器,它代表的是里面的具体某个元素(先这么理解)。
8:长度:
    size,length,empty
    string中,size和length是一样的!都是返回字符串长度。
    max_size();//返回当前字符串能存放的最大长度,一般为0xFFFFFFFE。为最最大值。
    capacity();//返回当前不增加长度能够存放的最大值。不用分配内存的情况下。
    resize();//eg:resize(100,'a');//重新分配内存,如果传入长度大于原来字符串长度,分配后会前面部分还是原来的,后面全部用传入的字符填充,如果没传入字符,默认为空格,如果长度小于原来的,那么就截取原来字符串前面部分放在里面。分配完成后,字符串总长度就是指定长度,这里是100。
int main()
{
string str;
std::cout << str.size() << std::endl;//返回the length of the string			//输出0
std::cout << str.length() << std::endl;//返回the length of the string			//输出0
std::cout << str.empty() << std::endl;//返回bool类型,为空返回1,不为空返回0		//输出1
std::cout << str.max_size() << std::endl;//返回最大长度					//输出0xFFFFFFFE
std::cout << str.capacity() << std::endl;//返回不用分配内存的情况些能装的最大长度//输出15
str = "1234567890123456";
std::cout << str.size() << std::endl;				//输出16
std::cout << str.length() << std::endl;				//输出16
std::cout << str.empty() << std::endl;//返回bool类型		//输出0
std::cout << str.max_size() << std::endl;			//输出0xFFFFFFFE
std::cout << str.capacity() << std::endl;
4000
//输出31

str.resize(100, 'a');
std::cout << str << std::endl;
std::cout << str.size() << std::endl;				//输出100
std::cout << str.length() << std::endl;				//输出100
std::cout << str.empty() << std::endl;//返回bool类型		//输出0
std::cout << str.max_size() << std::endl;			//输出0xFFFFFFFE
std::cout << str.capacity() << std::endl;			//输出111

return 0;
}


从上面可以看出,string类默认分配的空间为16字节,可以存放15个字符,每次大于15后就会增加长度(经测试,并不是*2,也不一定是加固定长度)。

9:string::find

    string.find();//返回的是位置pos。找到返回位置(std::size_t),未找到返回0xFFFFFFFF(-1或者std::string::npos)

    还有rfind,find_first_of,find_last_of,find_first_not_of,find_last_not_of。返回的都是位置pos。

int main()
{
string str = "0123456789";
std::string::size_type pos = str.find('3');//找到3位
std::cout << pos << std::endl;//输出的是下标,为3
pos = str.find('3',3);//从下标3开始往后面找,3也在范围内,默认为0。
std::cout << pos << std::endl;//输出下标3
pos = str.find("45");//找字符串
std::cout << pos << std::endl;//输出4
pos = str.find("7890", 3, 2);//从str下标3开始查找,找“7890”的前两个字符的字符串
std::cout << pos << std::endl;
//还可以传入本类对象参数。这里不做测试
//str.rfind();函数可find的一模一样,只是他是从末尾查找。他指定的开始位置也一样,但是是从开始位置往前面查找

return 0;
}


    find_first_of();//查找第一个是传入的字符串里面任意字符的值的值的位置。

    find_last_of();//查找最后一个是传入的字符串里面任意字符的值的值的位置。

    find_first_not_of();//查找第一个不是传入的字符串里面的任意字符值的值的位置。

    find_last_not_of();//查找最后一个不是传入的字符串里面的任意字符的值的值的位置。

    注意:这四个函数和find的参数都基本一样。特别注意的地方是他不算全匹配,他是字符串里面的任意字符匹配。

int main()
{
string str = "90123456789";
std::string::size_type pos = str.find_first_of("3012");	//返回1
std::cout << pos << std::endl;				//输出1

pos = str.find_first_not_of("90");			//返回2(下标)
std::cout << pos << std::endl;				//打印2
pos = str.find_first_not_of("1093");			//返回3,
std::cout << pos << std::endl;				//打印3
str = "99999999";
pos = str.find_first_not_of("901");			//找不到位置不是9或0或1
std::cout << pos << std::endl;				//输出0xFFFFFFFF

return 0;
}


10:compare:
    比较函数,与==类是,但是compare可以指定位置和长度进行比较,是全比较(连续字符串)。compare若比较是符合的,返回的是0。
11:substr:
    basic_string substr (size_type pos = 0, size_type len = npos) const;
    截取函数。传入位置和长度
12:swap:
    交换函数。两个string类对象直接交换数据。
13:其他函数:
    1:有对+=的重载,以下部分函数来源于http://www.cplusplus.com/
        string (1)

        basic_string& operator+= (const basic_string& str);

        c-string (2)

        basic_string& operator+= (const charT* s);

        character (3)

        basic_string& operator+= (charT c);
    2:append,字符串连接的。他可以制定连接位置和长度。
    3:assign,赋值。
    4:重载了[]和at();,两者基本一样,但是at()有检测,可以抛出可控的异常,程序员可以用try,catch,final来处理异常,[]直接抛出系统级异常,程序终止!
    5:insert,插入。
13:特别注意函数:
    1:.c_str:返回C风格的字符串,就是char*的字符串。
    2:.data:返回纯字符串,没有'\0'结束符。
14:类型转换顺序
    char->short->long->int->double;
    float->double;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编程