C++ Primer 5th 随堂练习
【C++ Primer】第三章 字符串、向量和数组 (练习)
第三章 字符串、向量和数组
练习 3.1
使用恰当的 using 声明重做 1.4.1 节(第 11 页)和 2.6.2 节(第 67 页)的练习。
解答
1.4.1 节:
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
int sum = 0;
for (int val = 1; val <= 10; ++val) {
sum += val;
}
cout << "Sum of 1 to 10 inclusive is " << sum << endl;
system("pause");
return 0;
}
2.6.2 节同理。
练习 3.2
编写一段程序从标准输入中一次读入一行,然后修改该程序使其一次读入一个词。
解答
每次读入一行:
#include <iostream>
#include <string>
using std::cin; using std::cout; using std::endl;
using std::string;
int main()
{
string line;
// 每次读入一整行, 直至到达文件末尾
while (getline(cin, line)) {
cout << line << endl;
}
system("pause");
return 0;
}
每次读入一词:
#include <iostream>
#include <string>
using std::cin; using std::cout; using std::endl;
using std::string;
int main()
{
string word;
// 每次读入一个词, 一旦遇到文件结束标记或非法输入便结束循环
while (cin >> word) {
cout << word << endl;
}
system("pause");
return 0;
}
练习 3.3
请说明 string 类的输入运算符和 getline 函数分别是如何处理空白字符的。
解答
- 类似 is >> s 的读取:在执行读取操作时,string 对象会 忽略开头的空白 (即空格符、换行符、制表符等) 并从第一个真正的字符开始读起,直到遇见下一处空白 为止。
- 类似 getline(is, s) 的读取:在执行读取操作时,string 对象会从输入流中读取内容,直到遇见换行符 为止 (注意换行符也被读进来了),然后把所读的内容存入到那个 string 对象中 (注意不存换行符)。
练习 3.4
编写一段程序读取两个字符串,比较其是否相等并输出结果。如果不相等,输出比较大的那个字符串。改写上述程序,比较输入的两个字符串是否等长,如果不等长,输出长度较大的那个字符串。
解答
比较结果:
#include <iostream>
#include <string>
using std::cin; using std::cout; using std::endl;
using std::string;
int main()
{
string s1, s2;
cin >> s1 >> s2;
if (s1 == s2) {
cout << "Two strings are equal" << endl;
}
// 可用海象运算符简化书写:
// else
// {cout << "The larger string is " << ((s1 > s2) ? s1 : s2) << endl;}
else if (s1 > s2) {
cout << "The larger string is " << s1 << endl;
}
else {
cout << "The larger string is " << s2 << endl;
}
system("pause");
return 0;
}
比较长度:
#include <iostream>
#include <string>
using std::cin; using std::cout; using std::endl;
using std::string;
int main()
{
string s1, s2;
cin >> s1 >> s2;
if (s1.size() == s2.size()) {
cout << "The lengthes of two strings are equal" << endl;
}
else {
cout << "The longer string is " << ((s1.size() > s2.size()) ? s1 : s2) << endl;
}
//else if (s1.size() > s2.size()) {
// cout << "The longer string is " << s1 << endl;
//}
//else {
// cout << "The longer string is " << s2 << endl;
//}
system("pause");
return 0;
}
练习 3.5
编写一段程序从标准输入中读入多个字符串并将他们连接起来,输出连接成的大字符串。然后修改上述程序,用空格把输入的多个字符串分割开来。
解答
连接字符串:
#include <iostream>
#include <string>
using std::cin; using std::cout; using std::endl;
using std::string;
int main()
{
string str, temp;
while (cin >> temp) {
str += temp;
}
cout << str << endl;
system("pause");
return 0;
}
空格分隔:
#include <iostream>
#include <string>
using std::cin; using std::cout; using std::endl;
using std::string;
int main()
{
string str, temp;
while (cin >> temp) {
str = str + temp + " "; // str += temp + " ";
}
cout << str << endl;
system("pause");
return 0;
}
练习 3.6
编写一段程序,使用范围 for 语句将字符串内所有字符用 X 代替。
解答
#include <iostream>
#include <string>
#include <cctype>
using std::cin; using std::cout; using std::endl;
using std::string;
int main()
{
string str;
cin >> str; // 不过一旦遇到空白就停止标准输入了
for (auto &s : str) { // 注意, 要使用引用才行 !
s = 'X'; // 注意单字符使用单引号 ' ', 字符串才使用双引号 " "
}
cout << str << endl;
system("pause");
return 0;
}
练习 3.7
就上一题完成的程序而言,如果将循环控制的变量设置为 char 将发生什么?先估计一下结果,然后实际编程进行验证。
解答
估计如果将循环控制的变量设置为 char,输出的字符串将仍会正常改变。验证:
#include <iostream>
#include <string>
#include <cctype>
using std::cin; using std::cout; using std::endl;
using std::string;
int main()
{
string str;
cin >> str; // 不过一旦遇到空白就停止标准输入了
for (char &s : str) { // 循环控制变量从 auto 改为了 char
s = 'X'; // 注意单字符使用单引号 ' ', 字符串才使用双引号 " "
}
cout << str << endl;
system("pause");
return 0;
}
练习 3.8
分别用 while 循环和传统 for 循环重写第一题的程序,你觉得哪种形式更好呢?为什么?
解答
传统 while 循环实现:
#include <iostream>
#include <string>
#include <cctype>
using std::cin; using std::cout; using std::endl;
using std::string;
int main()
{
string str;
cin >> str;
decltype(str.size()) index = 0; // 索引
while (index < str.size()) {
str[index] = 'X';
++index;
}
cout << str << endl;
system("pause");
return 0;
}
传统 for 循环实现:
#include <iostream>
#include <string>
#include <cctype>
using std::cin; using std::cout; using std::endl;
using std::string;
int main()
{
string str;
cin >> str;
for (decltype(str.size()) index = 0 ; index < str.size() ; ++index) {
str[index] = 'X';
}
cout << str << endl;
system("pause");
return 0;
}
综上可知,来自 C++ 11 的范围 for 语句比传统 while / for 语句更好,因为无需直接操作索引,相对更简洁了。
练习 3.9
下面的程序有何作用?它合法吗?如果不合法?为什么?
string s; cout << s[0] << endl;
解答
上述程序先定义了一个字符串 s,然而字符串 s 未初始化,默认为空字符串。然后,试图标准输出字符串 s 的首个字符。然而,对空字符串不可使用下标访问。因此,上述程序不合法。
练习 3.10
编写一段程序,读入一个包含标点符号的