1:首先区分开C和C++中的string
解释:C语言中的并没有string类型(C语言连类都没,当然没有string),C中的有个string.h头文件,这个头文件只是包含对字符串的处理,比如说strcat等函数。而C++中的string是一个标准库类型,表示可变长的字符序列,而由于是标准库类型,所以string定义在命名空间std中。
2:定义和初始化string对象
如何初始化类的对象是由类本身决定的。一个类可以定义很多种初始化对象的方式。
初始化string对象的方式
(1)string s1; //默认初始化,s1是一个空串
(2)string s2(s1); //s2是s1的副本
(3)string s3("value"); //s3是字面值“value”的副本,除了字面值最后那个空字符除外
(4)string s3 = "value"; //等价于上面
(5)string s4(n,'C'); //把s4初始化由连续n个字符c组成的串
这里初始化方式,是由string类中的默认构造函数、显示构造函数、赋值/拷贝构造函数决定的。
另外:string中的字符串,最后有没有'\0',C++11中的string以‘\0’结尾的,这是为了兼容C。
但是'\0'并不作为string的结束符,则string中的'\0'是允许在中间的,只不过显示是空而已。因为string类中已经记录了长度,并不需要'\0'来结尾。
验证:参考代码
1 #include<stdio.h>
2 #include<string>
3
4 int main()
5 {
6 std::string s1 = "abc";
7 if(s1[4] == '\0')
8 {
9 printf("yes!\n");
10 }
11 printf("s1_length=%d\n",s1.size());
12
13 return 0;
14 }
输出结果:
yes!
s1_length=3
3:string对象上的操作
列举string的一些操作:
os << s; //将s写到输出流os当中,返回os
is >> s; //从is中读取字符串赋给s,字符串以空白分隔,返回is
getline(is, s); //从is中读一行赋给s,返回is
s.empty(); //s为空返回true,否则返回false
s[n]; //返回s中第n个字符的引用,位置n从0计起
s.size(); //返回s中字符的个数
s1 + s2; //返回s1+s2连接后的结果
s1 = s2; //用s2的副本代替s1中原来的字符
s1 == s2; //如果s1和s2中所含的字符完全一样,则它们相等;string对象的相等性判断等字母的大小写敏感
s1 != s2;
<,<=,>,>=; //利用字符在字典中的顺序进行比较,且对字母的大小敏感
读写string对象
使用标准库中的iostream来读写int,double等内置类型值。也可以使用IO操作符读写string对象。
1 #include<stdio.h>
2 #include<string>
3 #include<iostream>
4
5 int main()
6 {
7 std::string s; //空字符串
8 std::cin >> s; //将string对象读入s,遇到空白停止
9 std::cout << s << std::endl; //输出s
10 return 0;
11 }
在执行读取操作时,string对象会自动忽略开头的空白(即空白符、换行符、制表符等)并从第一个真正的字符开始读起,知道遇到下一处空白为止。
如上所述,如果输入的是“ Hello World! ”,则将输出“Hello”,输出结果没有任何空格。
和内置类型的输入输出操作一样,string对象的此类操作也是返回运算符左侧的运算对象作为其结果。因此,多个输入或者多个输出可以连写在一起。
sting s1,s2;
cin >> s1 >> s2;
cout << s1 << s2 <<endl;
假设给上面这段程序输入与之前一样的内容“ Hello World! ”,输出将是“HelloWorld!”。
读取未知数量的string对象
1 #include<stdio.h>
2 #include<string>
3 #include<iostream>
4
5 int main()
6 {
7 std::string world ;
8 while(std::cin >> world)
9 {
10 std::cout << world << std::endl;
11 }
12 return 0;
13 }
这里注意的是,while循环会一直执行直至遇到文件结束符(或输入错误,如要求输入整数,实际输入不是整数),这个while其实是检测流的状态,因为cin返回左侧流的对象。
从键盘上输入文件结束符:在Windows系统中,输入文件结束符的方法是敲Ctrl + Z,然后按Enter或Return。在UNIX系统中,包括Mac OS X系统中,文件结束符输入是用Ctrl + D
至于为什么要加上endl。endl是一个被称为操纵符的特殊值,写入endl的效果是结束当前行,并将于设备关联的缓冲区中的内容刷到设备中。缓冲刷新操作可以保证到目前为止程序所产生的所有输出都真正写入输出流中,而不是仅停留在内存中等待写入流。
使用getline读取一整行
前面的用>>读取字符串时,是遇到空白符就结束的。可以用getline函数替代>>运算符,这样最终得到的字符串中保留输入时的空白符。getline函数的参数时一个输入流和一个string对象,函数从给定的输入流中读入内容,知道遇到换行符为止(注意这是换行符也被读进来),然后把所读的内容存入到那个string对象中(注意这里不存换行符)。getline只要一遇到换行符就结束读取操作并返回结果,哪怕输入的一开始就是换行符也是如此。如果输入真的一开始就是换行符,那么所得的结果就是空的string。
和输入>>运算符一样,getline也会返回它的流参数。因此既然输入运算符能作为判断的条件,也能用getline的结果作为判断的条件。
1 #include<stdio.h>
2 #include<string>
3 #include<iostream>
4
5 int main()
6 {
7 std::string world ;
8 // while(std::cin >> world)
9 // {
10 // std::cout << world << std::endl;
11 // }
12 while (getline(std::cin,world))
13 {
14 std::cout << world << std::endl;
15 }
16 return 0;
17 }
18
因为world中最后那个换行符最终是没有保存的,所以最后要加个endl。
string::size_type类型
如string中的操作,s.size()返回的是string::size_type类型的值。string类及其他大多数标准库类型都定义了几种配套的类型。这种配套类型体现了标准库类型与机器无关的特性,类型szie_type即是其中的一种。在具体使用时,通过作用域操作符来表明名字size_type是在类string中定义的。
size_type是一个无符号的值,而且足够存放下任何string对象的大小。可以用auto或者decltype来推断变量的类型。
auto len = s.size() ; //len的类型是string::size_type
由于size_type是一个无符号整型数,因此切记,如果在表达式中混用了带符号数和无符号数将可能产生意想不到的结果。例如,假设n是一个负值的int,则表达式s.size() < n的判断结果几乎肯定是true。这是因为负值n会自动转换成一个比较大的无符号值。所以表达式中有了size()函数就不用int了。
比较string对象
string对象比较对大小写敏感。
相等性运算符(==和!=)分别检验两个string对象相等或不相等,string对象相等意味着他们的长度相同而且所包含的字符也全部相同。
关系运算符(<,>=)按照字典顺序:(1)如果两个string对象的长度不同,而且较短string对象的每个字符都与较长string对象对应上的位置上的字符相同,就说较短的string对象小于较长的string对象。 (2)如果两个string对象在某些对应的位置上不一致,则string对象比较的结果其实是string对象中第一对相异字符比较的结果。
示例:
string str = "Hellp";
string phrase = "Hello World";
string slang = "Hiya";
根据(1)可以判断,对象str小于对象phrase,根据(2)可判断,对象slang既大于str也大于phrase。
为string对象幅值
string s1 = "aaa",s2;
s1 = s2;
这里就不解释了。。
两个string对象相加
两个string对象相加得到一个新的string对象,其内容是把左侧的运算对象与右侧的运算对象串接而成。
string s1 = "hello, ", s2 = "world\n";
string s3 = s1 + s2; //s3的内容是“hello, world\n”
字面值与string对象相加
因为标准库允许把字符字面值和字符串字面值转换成string对象,所以在需要string对象的地方就可以使用这两种字面值来替代。如 string s1 = "hello", s2 = "world";
string s3 = s1 + ", "(这里是字符串逗号加空格) + s2 + '\n';
但是注意:当把string对象和字符字面值及字符串字面值混在一条语句中时,必须确保每个加法运算符+的两侧对象至少有一个是string:
string s4 = s1 + ", "; //正确
string s5 = "hello" + “, ”; //错误
string s6 = s1 + ", " + “world"; //正确
string s7 = "hello" + ", " + s2; //错误
为什么s6正确而s7错误,因为s6可以转换成如下 s6 = (s1 + ", ") + “world”; 括号里s1 + ", "的结果是一个string对象。
还要注意一点:字符串字面值与string是不同的类型。
处理string对象中的字符
可以参考cctype头文件中的函数,如判断是否为数字,大小写字符等。