第三章 字符串,向量 和数组
开头简介:
String
:表示可变长的字符序列。
Vector
:存放的是 某种给定类型对象 的可变长序列
3.1 命名空间的Using 声明
-
Std::cin
-
::作用域操作符
含义: 编译器从左侧名字所示的作用域 寻找 右侧那个名字。
-
代码的意思: 使用命名空间Std中的名字cin。
-
- 文件中不应该包含 Using 声明
因为头文件的内容会拷贝到所有引用它的文件中去,如果头文件中有某个Using声明,那么每个使用了该头文件的文件都会有这个声明。因此,对于某些程序而言,由于不经意的包含了某些名字,反而可能产生始料未及的命名冲突。
3.2 标准库类型 string
3.2.1 定义和初始化string 对象
String s1; 默认初始化,s1是一个空串 |
String s2 = s1; s2是s1的副本 |
String s2(s1); 等价于s2 = s1; |
String s3("value"); s3是字面值value的副本,除了字面值最后的那个空字符外 |
String s3 = "value"; 等价于上一条 |
String s4(n,'c'); s4初始化为连续N个字符C的字符串 |
注: 当初始值只有一个时,用 拷贝初始化 和 直接初始化都行,当有多个值时,一般用直接初始化。
- 拷贝初始化
使用等号(=)初始化一个变量。
- 直接初始化
与之相反不使用等号(=)初始化就是直接初始化。
例如:string s5 = "hija"; 拷贝初始化
String s5("hija"); 直接初始化
String s6(8,'c'); 直接初始化
当然对于有多个值进行初始化也可以用 拷贝初始化,如下:
String s7 = string(8,'c'); //拷贝初始化
本质等价于:
String temp(8,'c');
String s7 = temp;
你觉得这种方法方法相对于直接初始化 如何????????
3.2.2 string 对象上的操作
os << s | 将 s 写到输出流 os 当中,返回os |
is >> s | 将is 读取的字符串赋给 S,字符串以空格分隔,返回is. |
getline(is,s) | 从is中读取一行,赋给s,返回is. |
s.empty() | s为空返回true,否则返回false |
s.size() | 返回s中字符串的个数 |
s[n] | 返回第n个字符的引用,位置n 从0计起 |
s1 + s2 | 返回是s1 和 s2连接后的结果 |
s1 = s2 | 将s2的副本替代s1中原来的字符 |
s1 == s2 | 判断所包含的字符是否完全一样,对字母大小写很敏感。 |
s1 != s2 | |
< ,<=, > ,>= | 利用字符在字典中的顺序进行比较,且对字母的大小写敏感 |
例子:
int main()
{
string s;
cin >> s; //在进行读取操作时,string对象会自动忽略开头的空白处,(空格,换行符,制表符等)并从第一个真正的字符开始,直到遇见下一处空白为止。
cout << s << endl;
return 0;
}
- 和内置类型的输入输出操作一样,string对象的此类操作也是返回运算符左侧的运算对象作为其结果。因此 : 多个输入和多个输出可以连在一起写。
例如:cin >> s1 >> s2;
cout << s1 << s2;
-
如果希望最终得到的字符串中保留输入时的空白符,那么使用函数getline(is,s)
is是一个输入流对象,s是一个string对象。
注意:函数从给定的输入流中读取内容,直到遇见换行符为止。(换行符也被读进来了),然后把读取的内容存入到string对象中(不存换行符)。即便一开始就是换行符,函数也会读取操作被返回结果,只不过结果是一个空string
- string::size_type类型
-
size函数返回string对象的长度(string对象中字符的个数)。但是返回类型是 string::size_type.
b) string类及其他大多数标准库类型都定义了几种配套的类型,这些配套类型体现了标准库类型与机器无关的特性,类型size_type就是其中一种。
size_type类型是一个无符号类型的值,而且能足够存放下任何string对象的大小。
c) c++11新增:
允许编译器通过auto 和 decltype推断变量的类型。
d) 由于size函数返回的是一个无符号类型,因此切记,如果在表达式中混用了带符号数和无符号数,将会带来意想不到的后果。例如:s.size() < n //n是一个int负值
这个结果永远为true,因为负数n自动转换为一个比较大的无符号数。
-
字面值和string对象相加
-
当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符(+)的两侧的运算对象至少有一个是string。
例如:
string s4 = s1 + ","; //正确
string s5 = "hello" + ","; //错误,两个运算对象都不是string .
string s6 = s1 + "," + " world";//正确。相当于
string temp = s1 + ","
string s6 = temp + "world"
string s7 = "hello" + "," + s2; //错误
WARING:
因为某些历史原因,也为了与C兼容,所以C++语言中的字符串字面值并不是标准库类型string对象。切记:字符串字面值与string是不同类型。
3.2.3 处理string对象中的字符
cctype头文件中的函数 | |
isalnum(c) | 当c是字母或者数字时,为真 |
isalpha(c ) | 当c是字母时为真 |
iscntrl(c) | 当C是控制字符时为真 |
isdigit( c ) | 当C是数字时为真 |
isgraph(c) | 当C不是空格但可但打印时为真 |
islower( c ) | 当C是小写字母时为真 |
isprint( c ) | 当C是可打印字符时为真(即C是空格或C具有可视形式) |
ispunct( c ) | 当C是标点符号时为真 |
isspace( c ) | 当C是空白时为真 (即C是空格,横向制表符,纵向制表符,回车键,换行符,进纸符中的一种) |
isupper( c ) | 当C是大写字母时为真 |
isxdigit( c ) | 当C是十六进制数字时为真 |
tolower( c ) | 转换成小写字母 |
toupper( c ) | 转化成大写字母 |
- 范围for语句
语法形式:
for( declaration : expression)
statement
例子:
string str("some string");
for ( auto c : str)
cout << c << endl;
//变量C和str联系了起来,每次迭代,str的下一个字符被拷贝给了C。
- 适用范围for语句改变字符串中的字符
如果想改变string对象中的字符,必须把循环变量定义成引用类型。
例如 for( auto &c : str)
-
只处理一部分字符
两种方法:1) 使用下标运算符[]
2) 使用迭代器
-
下标运算符
- 下标运算符[]接受的输入参数是 string::size_type类型的值。其实任何整型值都可以做索引,只不过如果这个索引是带符号的类型的值,那么将自动转换为string::size_type无符号类型。
-
if(!s.empty()) //确保确实有字符输出
cout << s[0] <<endl; //输出S的第一个字符。
其实不管何时,只要对string对象使用下标,都要确认在那个位置确实有值存在。
c)注意随时检查 下标的合法性
使用下标也可以执行随机访问。
-
迭代器( iterator )
3.4节----》处讲解