本文参考提取C++ PrimerPlus重要概念以供自己和别人学习。
推荐C++学习详细链接,内容丰富齐全,C++字符串类详解
1、构造字符串
介绍基础概念:
NBTS: (null-byte-terminated-string):以空字符串结束的字符串-传统C字符串,用于下面的描述。
npos: string类的static变量,值为unsigned long, 值为0xffffffff;
C++ string类的构造函数有以下六种方式
1.string(const char * s)
说明:将string对象初始化为s指向NBTS。NBTS为null-byte-temnated string的缩写,表示以空字符结束的字符串------传统的C字符串。
2.string(size_type n,char c)
说明:创建一个包含n个元素的string对象,其中每个元素都被初始化为字符c
3.string(const string & str,string size_type n = npos)
说明:将string对象初始化为对象str中从位置pos开始到结尾的字符,或从位置pos开始的n个字符
4.string()
说明:创建一个的string对象,长度为0
5.string(const char * s, size_type n)
说明:将string对象初始化为s指向的NBTS中的前n字符,即使超过了NBTS端
6.template string(Iter begin,Iter end)
说明:将string对象初始化为区间[begin,end]内的字符,其中begin和end的行为就像指针,用于指定位置,范围包括begin在内,但不包括end
以下代码将在#ctor 表示第几种构造方式
int str_test_ctor()
{
using namespace std;
cout << "npos:" << hex<< string::npos << endl;
string one("Lottery Winner!"); //ctor #1 string(const char* s)
cout <<"one:"<< one << endl;
string two(20, '$'); //ctor #2 string(size_type n,char c)
cout << "two:" << two << endl;
string three(one); //ctor #3 string(const string & str,string size_type n = npos)
cout << "three:" << three << endl;
string three1(one, 3); //从one下标为3的的地方开始到结束
cout <<"three1:" << three1 << endl;
string three11(one, 5); //从one下标为5的的地方开始到结束
cout << "three11:" << three11 << endl;
//string three2(one, string::npos); //溢出
//cout << "three2:" << three1 << endl;
one += "Oops!"; //重载+=,直接拼接
cout << one << endl;
two = "Sorry,That was"; //重载=,直接赋值
three[0] = 'P'; //重载[],取第几个元素
string four; //ctor #4 string()
four = two + three;
cout << four << endl;
char alls[] = "All's well that ends well";
string five(alls, 20); //ctor #5 string(const char * s, size_type n)
cout << five << "!\n";
string five1(alls, 40); //超出部分不会溢出,估计是直接分配了这么大,但是后面的没管
cout << five1 << "!\n";
string six(alls + 6, alls + 10); //ctor #6 template<clas Iter> string(Iter begin,Iter end)
cout << six << ", ";
string seven(&five[6], &five[10]); //ctor #6 again
cout << seven << "....\n";
return 0;
}
运行结果如下:
2、String类输入
(1)C-风格字符串,三种方式:
char info[100];
cin >> info; //read a word (I guess leave \n in queue,)
cin.getline(info, 100); //read a line,discard \n
cin.get(info, 100); //read a line, leave \n in queue
(2) string 对象,有两种方式
string stuff;
cin>>stuff; //read a word (I guess leave \n in queue,)
getline(cin,stuff); //read a line,discard \n
两个getline函数都有一个可选参数,用于指定哪个字符作为输入边界(终止输入字符)
cin.getlinne(info,100,’:’); //read a line,read upto ;, discard \n
getline(cin,stuff,‘:‘); //read a line,read upto ;, discard \n
加粗部分在C++ PrimerPlus 上产生错误的描述,幸好我聪明,贯通上下文,认识到函数本来模样;
void string_test_cin()
{
char info[100];
cout << "CIN for Info:";
memset(info, 0, sizeof(info));
cin >> info; //read a word
cout << "info :" << info << endl;
cin.getline(info, 100);
cout << "CIN for Info:";
memset(info, 0, sizeof(info));
cin.getline(info, 100); //read a line,discard \n
cout << "info :" << info << endl;
cout << "CIN for Info:";
memset(info, 0, sizeof(info));
cin.get(info, 100); //read a line, leave \n in queue
cout << "info :" << info << endl;
cin.getline(info, 100); //read a line,discard \n
string stuff;
cout << "CIN for Stuff:";
cin >> stuff;
cout << "stuff :" << stuff << endl; //read a word
getline(cin, stuff);
cout << "CIN for Stuff:";
getline(cin, stuff);
cout << "stuff :" << stuff << endl; //read a line,discard \n
cout << "CIN for Stuff:";
cin.getline(info, 100,':');
cout << "info :" << info << endl; //read a line,read upto ;, discard \n
//getline(cin,stuff, ':');
//cin.getline(stuff, ':');
//cout << "info :" << info << endl; //read a line,read upto ;, discard \n
}
运行结果如下
3、使用字符串
(1)重载6个关系操作符
int string_operator_test()
{
string snake1("cobra");
string snake2("cobrl");
if (snake1 < snake2)
cout << "<\n";
if (snake1 > snake2)
cout << ">\n";
if (snake1 == snake2)
cout << "==\n";
if (snake1 != snake2)
cout << "!=\n";
if (snake1 <= snake2)
cout << "<=\n";
if (snake1 >= snake2)
cout << ">=\n";
return 0;
}
运行结果:
4、常用函数
(1)字符串搜索
size_t find (const string& str, size_t pos = 0) const; //从索引0(n) 开始,找str找到返回首次出现的索引,否则返回npos
size_t find (const char* s, size_t pos = 0) const; //从索引 0(n) 开始,找c风格字符串-str找到返回首次出现的索引,否则返回npos
size_t find (const char* s, size_t pos, size_t n) const; //从索引 0(n) 开始到n,找c风格字符串-str找到返回首次出现的索引,否则返回npos
size_t find (char c, size_t pos = 0) const; //从索引 0(n) 开始,找c风格字符c 找到返回首次出现的索引,否则返回npos
其它函数也都有这四种格式的重载,但是查找方式不同
rfind :从右往左查找
find_first_of : 从左往右,查找参数字符串中任意字符首次出现在字符串中的索引
find_last_of : 从左往右,查找参数字符串中任意字符首次(最后)出现在字符串中的索引
find_first_not_of : 从左往右,查找第一个不被包含在参数字符串中的字符首次出现在字符串中的索引
find_last_not_of : 从右往左,查找第一个不被包含在参数字符串中的字符首次出现在字符串中的索引
demo如下:
int string_other_test()
{
string str = "abcdefghijklmnopqrstuvwxyz"; //请问是啥构造函数
string substr("lmn");
cout << "str.size()=" << str.size() << endl; //两个函数都是包含大小,不算字符串结束符
cout << "str.length()=" << str.length() << endl;
int index = string::npos;
index=str.find("def", 0); //从0开始,找"def",找到返回首次出现的索引,否则返回npos
if (index == string::npos) cout << "find failed\n";
else cout << "find at " << index << endl;
index = str.find("def", 0,5); //从索引0开始找到5,找"def",找到返回首次出现的索引,否则返回npos
if (index == string::npos) cout << "find failed\n";
else cout << "find at " << index << endl;
index = string::npos;
index = str.find(substr, 0); //从0(n) 开始,找substr("def"),找到返回首次出现的索引,否则返回npos
if (index == string::npos) cout << "find failed\n";
else cout << "find at " << index << endl;
//index = str.find(substr, 0,5); //no such func
index = string::npos;
index = str.find('z', 0); //从0(n) 开始,找字符z,找到返回首次出现的索引,否则返回npos
if (index == string::npos) cout << "find failed\n";
else cout << "find at " << index << endl;
str.append(str);
cout << "New str:" << str << endl;
index = string::npos;
index = str.rfind('x',52); //从 52n) 开始,从后向前 找到第一个字符'x'?
if (index == string::npos) cout << "rfind failed\n";
else cout << "rfind at " << index << endl;
index = string::npos;
index = str.rfind("xyz", 52); //从 52(n) 开始,从后向前 找到第一个字符串'xyz'?
if (index == string::npos) cout << "rfind failed\n";
else cout << "rfind at " << index << endl;
index = string::npos;
index = str.rfind("abc", 0,21); //从 52(n) 开始,从后向前 找到第一个字符'x'?
if (index == string::npos) cout << "rfind failed\n";
else cout << "rfind at " << index << endl;
index = string::npos;
index = str.rfind(substr, 52); //从 5(n) 开始,从后向前 找到第一个字符串?
if (index == string::npos) cout << "rfind failed\n";
else cout << "rfind at " << index << endl;
index = string::npos;
substr = "mux";
index = str.find_first_of(substr, 0); //从 0(n) 开始,从后向前 找到字符串substr中任意一个字符首次出现在str里的索引
if (index == string::npos) cout << "find_first_of failed\n";
else cout << "find_first_of at " << index << endl;
index = string::npos;
substr = "mux";
index = str.find_last_of(substr, 52); //从 0(n) 开始,从后向前 找到字符串substr中任意一个字符最后一次出现在str里的索引
if (index == string::npos) cout << "find_first_of failed\n";
else cout << "find_first_of at " << index << endl;
index = string::npos;
substr = "mux";
index = str.find_first_not_of(substr, 0); //从 0(n) 开始,从后向前 找到字符串str里第一个不被包含在substr中任意一个字符的索引
if (index == string::npos) cout << "find_first_of failed\n";
else cout << "find_first_of at " << index << endl;
index = string::npos;
substr = "mux";
index = str.find_last_not_of(substr, 52); //从 0(n) 开始,从后向前 找到字符串str里第(最后)一个不被包含在substr中任意一个字符的索引
if (index == string::npos) cout << "find_first_of failed\n";
else cout << "find_first_of at " << index << endl;
return 0;
}
运行结果如图:
(2) 字符串增删改
operator+= :四种方式重载,追加
append:
==学了STL 再回来补这部分
(3)其它函数
tostring : 数字等,转换成string
c_str :返回字符串
substr : 返回字串
C++特性简直多的不要不要的,不再赘述;