3.2.3 处理string对象中的字符(3)
提示:注意检查下标的合法性
使用下标时必须确保其在合理范围之内,也就是说,下标必须大于等于0而小于字符串的size()的值。一种简便易行的方法是,总是设下标的类型为string::size_type,因为此类型是无符号数,可以确保下标不会小于0。此时,代码只需保证下标小于size()的值就可以了。
C++(www.cppentry.com)标准并不要求标准库检测下标是否合法。一旦使用了一个超出范围的下标,产生不可预知的结果。
使用下标执行随机访问
在之前的示例中,我们让字符串的下标每次加1从而按顺序把所有字符改写成了大写形式。其实也能通过计算得到某个下标值,然后直接获取对应位置的字符,并不是每次都得从前往后依次访问。
例如,想要编写一个程序把0到15之间的十进制数转换成对应的十六进制形式,只需初始化一个字符串令其存放16个十六进制"数字":
- const string hexdigits = "0123456789ABCDEF"; // 可能的十六进制数字
- cout << "Enter a series of numbers between 0 and 15"
- << " separated by spaces. Hit ENTER when finished: "
- << endl;
- string result; // 用于保存十六进制的字符串
- string::size_type n; // 用于保存从输入流读取的数
- while (cin >> n)
- if (n < hexdigits.size()) // 忽略无效输入
- result += hexdigits[n]; // 得到对应的十六进制数字
- cout << "Your hex number is: " << result << endl;
假设输入的内容如下:
- 12 0 5 15 8 15
程序的输出结果将是:
- Your hex number is: C05F8F
上述程序的执行过程是这样的:首先初始化变量hexdigits令其存放从0到F的十六进制数字,注意我们把hexdigits声明成了常量(参见2.4节,第59页),这是因为在后面的程序中不打算再改变它的值。在循环内部使用输入值n作为hexdigits的下标,hexdigits[n]的值就是hexdigits内位置n处的字符。例如,如果n是15,则结果是F;如果n是12,则结果是C,以此类推。把得到的十六进制数字添加到result内,最后一并输出。
无论何时用到字符串的下标,都应该注意检查其合法性。在上面的程序中,下标n是string::size_type类型,也就是无符号类型,所以n可以确保大于或等于0。在实际使用时,还需检查n是否小于hexdigits的长度。
3.2.3节练习
练习3.6:编写一段程序,使用范围for语句将字符串内的所有字符用X代替。
练习3.7:就上一题完成的程序而言,如果将循环控制变量的类型设为char将发生什么?先估计一下结果,然后实际编程(www.cppentry.com)进行验证。
练习3.8:分别用while循环和传统的for循环重写第一题的程序,你觉得哪种形式更好呢?为什么?
练习3.9:下面的程序有何作用?它合法吗?如果不合法,为什么?
- string s;
- cout << s[0] << endl;
练习3.10:编写一段程序,读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余的部分。
练习3.11:下面的范围for语句合法吗?如果合法,c的类型是什么?
- const string s = "Keep out!";
- for (auto &c : s) { /* ... */ }