第三章 字符串,向量和数组
3.1
Part A
// use `using` for 1.4.1
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
int sum = 0, val = 1;
// keep executing the while as long as val is less than or equal to 10
while (val <= 10) {
sum += val;
++val;
}
cout << "Sum of 1 to 10 inclusive is " << sum << endl;
return 0;
Part B
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
using std::cerr;
struct Sales_data {
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
int main()
{
Sales_data data1, data2;
// code to read into data1 and data2
double price = 0; // price per book, used to calculate total revenue
// read the first transactions: ISBN, number of books sold, price per book
cin >> data1.bookNo >> data1.units_sold >> price;
// calculate total revenue from price and units_sold
data1.revenue = data1.units_sold * price;
// read the second transaction
cin >> data2.bookNo >> data2.units_sold >> price;
data2.revenue = data2.units_sold * price;
// code to check whether data1 and data2 have the same ISBN
// and if so print the sum of data1 and data2
if (data1.bookNo == data2.bookNo) {
unsigned totalCnt = data1.units_sold + data2.units_sold;
double totalRevenue = data1.revenue + data2.revenue;
// print: ISBN, total sold, total revenue, average price per book
cout << data1.bookNo << " " << totalCnt << " " << totalRevenue << " ";
if (totalCnt != 0)
cout << totalRevenue / totalCnt << endl;
else
cout << "(no sales)" << endl;
return 0; // indicate success
}
else { // transactions weren't for the same ISBN
cerr << "Data must refer to the same ISBN" << endl;
return -1; // indicate failure
}
}
3.2
part A
// read the standard input a line at a time.
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
using std::getline;
int main()
{
string input;
while (getline(cin, input)) cout << input << endl;
return 0;
}
part B
// read the standard input a word at a time
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string word;
while (cin >> word) cout << word << endl;
return 0;
}
3.3
在执行读取操作时,string对象会自动忽略开头的空白(即空格符,换行符,制表符等),并从一个真正的字符开始读起,直到遇见下一处空白为止。
getline函数从给定的输入流读入内容,直到遇到换行符,然后把所读的内容存入到那个string对象中去(不存换行符)。
3.4
part A
// read two strings and report whether the strings are equal
// If not, report which of the two is larger.
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string str1, str2;
while (cin >> str1 >> str2) {
if (str1 == str2)
cout << "The two strings are equal." << endl;
else
cout << "The larger string is " << ((str1 > str2) ? str1 : str2);
}
return 0;
}
part B
// read two strings and report whether the strings have the same length
// If not, report which is longer
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string str1, str2;
while (cin >> str1 >> str2) {
if (str1.size() == str2.size())
cout << "The two strings have the same length." << endl;
else
cout << "The longer string is "
<< ((str1.size() > str2.size()) ? str1 : str2);
}
return 0;
}
3.5
part A
// read strings from the standard input, concatenating what is read into one
// large string.
// Print the concatenated string.
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string largeStr;
string str;
while (cin >> str) {
largeStr += str;
}
cout << "The concatenated string is " << largeStr << endl;
return 0;
}
part B
// separate adjacent input strings by a space.
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string largeStr;
string str;
while (cin >> str) {
if (largeStr.empty())
largeStr += str;
else
largeStr += " " + str;
}
cout << "The concatenated string is " << largeStr << endl;
return 0;
}
3.6
// Use a range for to change all the characters in a string to X.
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
int main()
{
string str("a simple string");
for (auto& c : str) c = 'X';
cout << str << endl;
return 0;
}
3.7
没有不同,通过使用auto关键字让编译器来决定变量c的类型,这里c的类型是char。
3.8
// Use a range for to change all the characters in a string to X.
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
int main()
{
string str("a simple string");
// use while
decltype(str.size()) i = 0;
while (i < str.size()) {
str[i] = 'X';
++i;
}
cout << str << endl;
// use traditional for
for (i = 0; i < str.size(); ++i) str[i] = 'Y';
cout << str << endl;
// I like the first one.
return 0;
}
3.9
不合法。因为s为空,s[0]的结果将是未定义的。在访问指定字符之前,首先检查s是否为空。
3.10
// reads a string of characters including punctuation and writes what was read
// but with the punctuation removed.
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::cin;
using std::endl;
int main()
{
string s;
cout << "Enter a string of characters including punctuation." << endl;
while (getline(cin, s)) {
for (auto i : s)
if (!ispunct(i)) cout << i;
cout << endl;
}
return 0;
}
3.11
c的类型是字符型常量引用,只要不改变c的值,都是合法的,否则是非法的。
3.12
(a)合法(c++11),其对象是vector对象。
(b)不合法,两个vector对象的类型必须相同。
(c)合法,有10个“null"。
3.13
(a)初始状态为空,没有元素。
(b)10个元素,都是0。
(c)10个元素,都是42。
(d)1个元素,是10。
(e)2个元素,10和42。
(f)10个默认初始化的元素。
(g)10个值为”hi"的元素。
3.14
#include <iostream>
#include <vector>
int main()
{
std::vector<int> vec;
int i;
while (std::cin >> i) vec.push_back(i);
return 0;
}
3.15
include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector<std::string> vec;
std::string str;
while (std::cin >> str) vec.push_back(str);
return 0;
}
3.16
#include <iostream>
#include <vector>
#include <string>
using std::vector;
using std::string;
using std::cout;
using std::endl;
int main()
{
vector<int> v1;
cout << "{\n \"v1\":{\"size\":\"" << v1.size() << "\",\"value\":[";
for (auto i : v1) cout << i << ",";
if (!v1.empty()) cout << "\b";
cout << "]}" << endl;
vector<int> v2(10);
cout << " \"v2\":{\"size\":\"" << v2.size() << "\",\"value\":[";
for (auto i : v2) cout << i << ",";
if (!v2.empty()) cout << "\b";
cout << "]}" << endl;
vector<int> v3(10, 42);
cout << " \"v3\":{\"size\":\"" << v3.size() << "\",\"value\":[";
for (auto i : v3) cout << i << ",";
if (!v3.empty()) cout << "\b";
cout << "]}" << endl;
vector<int> v4{10};
cout << " \"v4\":{\"size\":\"" << v4.size() << "\",\"value\":[";
for (auto i : v4) cout << i << ",";
if (!v4.empty()) cout << "\b";
cout << "]}" << endl;
vector<int> v5{10, 42};
cout << " \"v5\":{\"size\":\"" << v5.size() << "\",\"value\":[";
for (auto i : v5) cout << i << ",";
if (!v5.empty()) cout << "\b";
cout << "]}" << endl;
vector<string> v6{10};
cout << " \"v6\":{\"size\":\"" << v6.size() << "\",\"value\":[";
for (auto i : v6)
if (i.empty())
cout << "(null)"
<< ",";
else
cout << i << ",";
if (!v6.empty()) cout << "\b";
cout << "]}" << endl;
vector<string> v7{10, "hi"};
cout << " \"v7\":{\"size\":\"" << v7.size() << "\",\"value\":[";
for (auto i : v7)
if (i.empty())
cout << "(null)"
<< ",";
else
cout << i << ",";
if (!v7.empty()) cout << "\b";
cout << "]}\n}" << endl;
return 0;
}
3.17
#include <iostream>
#include <vector>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;
int main()
{
vector<string> vec;
string word;
while (cin >> word) vec.push_back(word);
for (auto& str : vec)
for (auto& c : str) c = toupper(c);
for (decltype(vec.size()) i = 0; i != vec.size(); ++i) {
if (i != 0 && i % 8 == 0) cout << endl;
cout << vec[i] << " ";
}
cout << endl;
return 0;
}
3.18
#include <vector>
using std::vector;
int main()
{
vector<int> ivec{0};
ivec[0] = 42;
return 0;
}
3.19
#include <iostream>
#include <vector>
using std::vector;
int main()
{
vector<int> ivec1(10, 42);
vector<int> ivec2{42, 42, 42, 42, 42, 42, 42, 42, 42, 42};
vector<int> ivec3;
for (int i = 0; i != 10; ++i) ivec3.push_back(42);
std::cout << "The first approach is better!" << std::endl;
}
3.20
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
using std::cin;
int main()
{
vector<int> ivec;
int i;
while (cin >> i) ivec.push_back(i);
if (ivec.empty()) {
cout << "input at least one integer." << endl;
return -1;
}
else if (ivec.size() == 1) {
cout << ivec[0] << " don't have any adjacent elements.";
}
else {
for (decltype(ivec.size()) i = 0; i != ivec.size() - 1; ++i)
cout << ivec[i] + ivec[i + 1] << " ";
}
cout << endl;
decltype(ivec.size()) size = ivec.size();
if (size % 2 != 0)
size = size / 2 + 1;
else
size /= 2;
for (decltype(ivec.size()) i = 0; i != size; ++i)
cout << ivec[i] + ivec[ivec.size() - i - 1] << " ";
cout << endl;
return 0;
}
3.21
#include <vector>
#include <iterator>
#include <string>
#include <iostream>
using std::vector;
using std::string;
using std::cout;
using std::endl;
void check(const vector<int>& vec)
{
if (vec.empty())
cout << "size: 0; no values." << endl;
else {
cout << "size: " << vec.size() << "; values:";
for (auto it = vec.begin(); it != vec.end(); ++it) cout << *it << ",";
cout << "\b." << endl;
}
}
void check(const vector<string>& vec)
{
if (vec.empty())
cout << "size: 0; no values." << endl;
else {
cout << "size: " << vec.size() << "; values:";
for (auto it = vec.begin(); it != vec.end(); ++it)
if (it->empty())
cout << "(null)"
<< ",";
else
cout << *it << ",";
cout << "\b." << endl;
}
}
int main()
{
vector<int> v1;
vector<int> v2(10);
vector<int> v3(10, 42);
vector<int> v4{10};
vector<int> v5{10, 42};
vector<string> v6{10};
vector<string> v7{10, "hi"};
check(v1);
check(v2);
check(v3);
check(v4);
check(v5);
check(v6);
check(v7);
return 0;
}
3.22
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::endl;
int main()
{
vector<string> text;
for (string line; getline(cin, line);) text.push_back(line);
for (auto it = text.begin(); it != text.end() && !it->empty(); ++it) {
for (auto& c : *it) c = toupper(c);
cout << *it << endl;
}
return 0;
}
3.23
#include <vector>
#include <iostream>
#include <iterator>
using std::vector;
using std::iterator;
using std::cout;
using std::endl;
int main()
{
vector<int> ivec(10, 1);
for (auto it = ivec.begin(); it != ivec.end(); ++it) *it *= 2;
for (auto value : ivec) cout << value << " ";
cout << endl;
return 0;
}
3.24
#include <iostream>
#include <vector>
#include <iterator>
using std::vector;
using std::cout;
using std::endl;
using std::cin;
int main()
{
int i;
vector<int> ivec;
while (cin >> i) ivec.push_back(i);
if (ivec.empty()) {
cout << "input at least one integer." << endl;
return -1;
}
else if (ivec.size() == 1) {
cout << *ivec.begin() << " has no adjacent elements.";
}
for (auto it = ivec.begin(); it + 1 != ivec.end(); ++it)
cout << *it + *(it + 1) << " ";
cout << endl;
for (auto beg = ivec.begin(), end = ivec.end() - 1; beg <= end;
++beg, --end)
cout << *beg + *end << " ";
cout << endl;
return 0;
}
3.25
#include <vector>
#include <iterator>
#include <iostream>
using std::vector;
using std::cout;
using std::cin;
using std::endl;
int main()
{
vector<unsigned> scores(11, 0);
unsigned grade;
while (cin >> grade)
if (grade <= 100) ++(*(scores.begin() + grade / 10));
for (auto score : scores) cout << score << " ";
cout << endl;
return 0;
}
3.26
vector迭代器运算中不支持两个迭代器相加,只支持两个迭代器相减,或一个迭代器与整数值的加减。
3.27
(a) 非法,维度必须是一个常量表达式。
(b)合法。
(c)非法,返回值不是常量表达式。
(d)非法,没有空间可存放空字符。
3.28
string不是内置类型,其支持无须显式初始化而定义对象,没有指定初值则生成一个空串,ia,ia2是内置类型,ia在函数体之外被初始化为0,ia2在函数体内部将不被初始化,其值是未定义的。
3.29
数组大小确定不变,不能随意向数组中增加元素。
3.30
数组索引从0开始,所以ix应该小于array_size,不可以等于。
3.31
#include <cstddef>
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int ia[10];
for (size_t i = 0; i < 10; ++i) ia[i] = i;
for (auto i : ia) cout << i << " ";
cout << endl;
return 0;
}
3.32
#include <cstddef>
#include <iostream>
#include <vector>
#include <iterator>
using std::cout;
using std::endl;
using std::vector;
using std::iterator;
int main()
{
// use array
int ia[10];
for (size_t i = 0; i < 10; ++i) ia[i] = i;
int ia2[10];
for (size_t i = 0; i < 10; ++i) ia2[i] = ia[i];
// use vector
vector<int> iv(10);
for (auto iter = iv.begin(); iter != iv.end(); ++iter)
*iter = iter - iv.begin();
vector<int> iv2(iv);
for (auto i : iv2) cout << i << " ";
cout << endl;
return 0;
}
3.33
不初始化数组将含有未定义的值。
3.34
相当于p1=p2; 只要p1和p2都合法,则该程序一直合法。
3.35
#include <iostream>
#include <iterator>
using std::begin;
using std::end;
using std::cout;
using std::endl;
int main()
{
int arr[10];
int* b = begin(arr);
int* e = end(arr);
for (int* i = b; i != e; ++i) *i = 0;
for (auto i : arr) cout << i << " ";
cout << endl;
return 0;
}
3.36
#include <iostream>
#include <vector>
#include <iterator>
using std::begin;
using std::end;
using std::cout;
using std::endl;
using std::vector;
// pb point to begin of the array, pe point to end of the array.
bool compare(int* const pb1, int* const pe1, int* const pb2, int* const pe2)
{
if ((pe1 - pb1) != (pe2 - pb2)) // have different size.
return false;
else {
for (int *i = pb1, *j = pb2; (i != pe1) && (j != pe2); ++i, ++j)
if (*i != *j) return false;
}
return true;
}
int main()
{
int arr1[3] = {0, 1, 2};
int arr2[3] = {0, 2, 4};
if (compare(begin(arr1), end(arr1), begin(arr2), end(arr2)))
cout << "The two arrays are equal." << endl;
else
cout << "The two arrays are not equal." << endl;
cout << "==========" << endl;
vector<int> vec1 = {0, 1, 2};
vector<int> vec2 = {0, 1, 2};
if (vec1 == vec2)
cout << "The two vectors are equal." << endl;
else
cout << "The two vectors are not equal." << endl;
return 0;
}
3.37
输出数组ca的所有元素。whiile循环检测空字符,需在数组最后一个字符后添加一个空字符。
3.38
因为两个指针相减可以得到在内存区域的相位差(距离),加减一个整数可以表明指针的前后移动。两个指针相加在逻辑上没有意义。
3.39
#include <iostream>
#include <string>
#include <cstring>
using std::cout;
using std::endl;
using std::string;
int main()
{
// use string.
string s1("Mooophy");
string s2("Pezy");
if (s1 == s2)
cout << "same string." << endl;
else if (s1 > s2)
cout << "Mooophy > Pezy" << endl;
else
cout << "Mooophy < Pezy" << endl;
cout << "=========" << endl;
// use C-Style character strings.
const char* cs1 = "Wangyue";
const char* cs2 = "Pezy";
auto result = strcmp(cs1, cs2);
if (result == 0)
cout << "same string." << endl;
else if (result < 0)
cout << "Wangyue < Pezy" << endl;
else
cout << "Wangyue > Pezy" << endl;
return 0;
}
3.40
#include <cstring>
#include <iostream>
using std::cout;
using std::endl;
int main()
{
const char cstr1[] = "Hello";
const char cstr2[] = "world!";
size_t new_size = strlen(cstr1) + strlen(" ") + strlen(cstr2) + 1;
char* cstr3 = new char[new_size];
strcpy(cstr3, cstr1);
strcat(cstr3, " ");
strcat(cstr3, cstr2);
std::cout << cstr3 << std::endl;
delete [] cstr3;
}
3.41
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
using std::begin;
using std::end;
int main()
{
int int_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<int> ivec(begin(int_arr), end(int_arr));
for (auto i : ivec) cout << i << " ";
cout << endl;
return 0;
}
3.42
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
using std::begin;
using std::end;
int main()
{
vector<int> ivec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int int_arr[10];
for (int* i = begin(int_arr); i != end(int_arr); ++i)
*i = ivec[i - begin(int_arr)];
for (auto i : int_arr) cout << i << " ";
cout << endl;
return 0;
}
3.43
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
// a range for to manage the iteration
for (const int(&p)[4] : ia)
for (int q : p) cout << q << " ";
cout << endl;
// ordinary for loop using subscripts
for (size_t i = 0; i != 3; ++i)
for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " ";
cout << endl;
// using pointers.
for (int(*p)[4] = ia; p != ia + 3; ++p)
for (int* q = *p; q != *p + 4; ++q) cout << *q << " ";
cout << endl;
return 0;
}
3.44
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
// a range for to manage the iteration
// use type alias
using int_array = int[4];
for (int_array& p : ia)
for (int q : p) cout << q << " ";
cout << endl;
// ordinary for loop using subscripts
for (size_t i = 0; i != 3; ++i)
for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " ";
cout << endl;
// using pointers.
// use type alias
for (int_array* p = ia; p != ia + 3; ++p)
for (int* q = *p; q != *p + 4; ++q) cout << *q << " ";
cout << endl;
return 0;
}
3.45
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
// a range for to manage the iteration
for (auto& p : ia)
for (int q : p) cout << q << " ";
cout << endl;
// ordinary for loop using subscripts
for (size_t i = 0; i != 3; ++i)
for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " ";
cout << endl;
// using pointers.
for (auto p = ia; p != ia + 3; ++p)
for (int* q = *p; q != *p + 4; ++q) cout << *q << " ";
cout << endl;
return 0;
}