02、c++ primer之string

来源:互联网 发布:数据线材厂家 编辑:程序博客网 时间:2024/05/15 09:39

今天看了string和vector,感觉比起之前用C语言操作是要方便很多,但是又多了许多的规则要记住,c++学习是个漫长的过程啊。

标准库类型的string是表示可变长字符序列。用之前要先包含头文件#include <string>,还有就是string是属于std这个命名空间的,所以要惯例加上using namespace std;

string初始化

先来说说怎么初始化string:有两种初始化方式,一种的直接初始化,另外一种是拷贝初始化。

string s1;//默认初始化一个空串string s2(s1);//s2是s1的副本string s2 = s1;//等价于上面string s3("value");//s3是字面值“value”的副本,出了最后的‘\0’string s3 = "value";//同上string s4(n,'c');//把s4初始化为n个字符c组成的串

直接初始化和拷贝初始化很容易区分,就是看有没有赋值号(=),有的话就是拷贝初始化。

string对象上的操作

os<<s  将s写到输出流os中,返回os
is>>s 从is中读取字符串给s,字符串以空白分隔,返回is
getline(is,s)  从is中读取一行赋给s,返回iss.empty()  s为空返回true,否则返回falses.size()  返回s中字符的个数s[n]  返回s中第n个引用的,位置从0计起s1 + s2  返回s1和s2连接后的结果s1 = s2  用s2来替代s1中原来的字符s1 == s2  如果字符完全一样返回他们相等s1 != s2 <,<=,>,>=  利用字典中的顺序进行比较,且对大小写敏感。

在读取操作时候string对象回自动忽略开头的空白(即空格符,换行符,制表符等)并从第一个真正的字符开始读起,只要遇见下一处空白为止。
例如,输入的是“     Hello  World    ”,输出的将是"Hello"。输出结果中没有任何空格。
输入和输出一样,也都是从非空白第一个字符算起,到第一个空白结束。
cin >> s1 >> s2;cout << s1 << s2;

依旧把上面的输入,这时候输出的就是“Hello World”。
这是需要记住的是空白是结束。第一个非空白的开始。

读取未知数量的string对象

用while(cin >> s),可以用于读取未知数量的字符串,但是你会发现问题来了,不能退出了。
这里对这个做分析:
因为cin是标准输入,作用就是接收来自终端的输入然后送入缓冲区中,当正确输入后,返回的是真。所以就退出不了。只有当检测到EOF也就是流的结束时候才能退出。流结束标志是 Ctrl+Z 或者 Ctrl+D 键按下作出检查。其检查的方式有两种:阻塞式以及非阻塞式。
    1. 阻塞式:windows一般用这种方法,这种方法是输入结束后再判断时候有Ctrl+Z,如果有就结束。所以,当你输入完就Ctrl+Z的话,这时候回自动把Ctrl+Z给忽略了,没有起作用,依然不能退出,这里只能输入完后回车,然后再Ctrl+Z,在回车,这时候就能退出来了。
    2. 非阻塞式:unix和linux一般用是的这个,这个退出就比windows方便多了,你只需要输入完回车,然后Ctrl+D,就退出了。不用再由cin来判断了。

使用getline读取一整行

getline函数的参数是一个参数输入流和一个string对象,就是从输入流中读入内容直到遇到换行符为止,这时候换行符也被读进来了,但是返回时候就把换行符给丢弃了,得到的string对象是没有换行符的。

比较string对象

string的比较是按照字典顺序来比较的:
1、如果两个string对象的长度不同,而且比较短的string对象的每个字符都与较长的string的对象相对应位置上的字符相同,就说较短的string对象小于较长的string对象。
2、如果两个string对象再某些对应的位置上不一致,则string对象比较的结果其实就是string对象中第一对相异字符比较的结果

这个是书上的原话比较拗口。用大白话来说就是
1、比较两个string对象,如果其中一个是另一个的一部分,那么这个少的就是小于。
2、完全不同时候,就一个字符一个字符比较,直到第一对不同的字符,那么比较的就是他们俩个了。
string str1 = "Hello";string str2 = "HelloWorld"string str3 = "Hiya"

用上面就规则可以看出str1就是str2你一部分所以 str1 < str2。然后看str1和str2他们第一个字符相同都是'H',但是第二个字符就不同了,所以我们需要比较的是‘e’和‘i’,又因为‘e’ < 'i',所以str1<str2。

处理string字符串

对字符串的操作自然不用多说,很多情况下都是在做字符的处理,什么变个大写,正则表达式,等等,c++给我们提供一些函数可以处理一些简单的字符串,这些函数在cctype这个头文件里。

isalnum(c) 当c是字母数字,即字母或数字,该函数返回trueisalpha(c) 当c是字母,该函数返回真isblank(c)  当c是空格或水平制表符,该函数返回trueiscntrl(c) 当c是控制字符,该函数返回trueisdigit(c) 当c是数字(0~9),该函数返回trueisgraph(c) 当c是除空格之外的打印字符,该函数返回trueislower(c) 当c是小写字母,该函数返回trueisprint(c) 当c是打印字符(包括空格),该函数返回trueispunct(c) 当c是标点符号,该函数返回trueisspace(c) 当c是标准空白字符,如空格、进纸、换行符、回车、水平制表符或者垂直制表符,该函数返回trueisupper(c) 当c是大写字母,该函数返回trueisxdigit(c) 当c是十六进制的数字,即0~9、a~f、A~F,该函数返回truetolower(c) 当c是大写字符,则返回其小写,否则返回该参数toupper(c) 当c是小写字母,则返回其大写,否则返回该参数

当我们处理字符串里每个字符时候,我们最好用range for
for (declaration : expression)
statement
举个栗子来说明这货怎么用:
string str("hello world");for (auto c : str){    cout << c << endl;}
range for有两个参数,第一个表示每次取出来了那个元素,第二个就是我们要取的那个字符串,这样就很容易理解了,循环的次数取决于元素的个数,这种for和传统的for相比:
    1. 优点是不用人为判断循环次数,减少错误;
    2. 缺点恰恰也是优点,我们不能人为的限定循环次数。
上面的那种方法是不能修改字符串的,因为当中只是简单的拷贝给了c并不是真正的str里的元素,所以只要把改成&c,直接使用引用就可以了。
//把s全部转化成大写string s("hello world");for (auto &c : s){     c = toupper(c);}cout << s << endl;


string对象也有下表操作,就是类似于数组的那个。要注意的几个问题是:
  1. 下标操作每次操作一个字符
  2. 从0算起,到s.size()-1为止
  3. 访问未知空间(小于0,大于s.size()-1)将发生不可预测错误
  4. 下表类型是string::size_type这是个非负的数

总结:

string的操作重要性相比都很清楚,在实际过程中,无论是软件开发,web开发,web后台开发,就连嵌入式开发,有很大一部分时间都是在对字符串进行操作。字符串也是人和计算机的广泛的交互方式。








0 0
原创粉丝点击