Exercise 3.2

1
2
3
4
5
6
7
8
9
int main()
{
  string s1, s2;
  getline(cin, s1);
  cout << s1 << endl;
  cin >> s2;
  cout << s2 << endl;
}

Exercise 3.3

1
2
3
// std::cin >> string object, space is ignored, words are read in one by one which are separted by space or spaces
// getline(std::cin, string object), reads a whole sentence until encounters a '\n', while that '\n' is not sotred in that string object.

Exercise 3.4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
int main()
{
  string s1, s2;
  getline(getline(cin, s1), s2); // getline returns cin object
  if(s1 != s2)
    {
      if(s1 > s2) cout << s1 << endl;
      else cout << s2 << endl;
    }
  if(s1.size() != s2.size())
    {
      if(s1.size() > s2.size()) cout << s1 << endl;
      else cout << s2 << endl;
    }
}

Exercise 3.5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int main()
{
  string result, s;
  while(getline(cin, s))
    {
      result += s;
      result += " ";
    }
  cout << result;
}

Exercise 3.6

1
2
3
4
5
6
7
8
9
int main()
{
  string s;
  getline(cin, s);
  for(auto &c : s)
    c = 'X';
  cout << s << std::endl;
}

Exercise 3.7

1
2
3
4
5
6
7
8
9
int main()
{
  string s;
  getline(cin, s);
  for(char c : s)		// c is a copy of character in string s
    c = 'X';
  cout << s << std::endl;	// actually s is unchanged
}

Exercise 3.8

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int main()
{
  string s;
  getline(cin, s);
  // decltype(s.size()) index = 0;
  // while(index != s.size())
  //   {
  //     s[index] = 'X';
  //     ++index;
  //   }
  for(decltype(s.size()) index = 0; index != s.size(); ++index)
    s[index] = 'X';		// using for is more user-friendly
  cout << s << std::endl;
}

Exercise 3.9

1
2
3
4
5
6
int main()
{
  std::string s;
  std::cout << s[0] << std::endl;		// illegal, s is an empty string, s[0] is undefined
}

Exercise 3.10

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int main()
{
  string s, result;
  getline(cin, s);
  for(auto c : s)
    {
      if(!ispunct(c)) result += c;
    }
  cout << result << std::endl;
}

Exercise 3.11

1
2
3
4
5
6
7
int main()
{
  const std::string s = "keep out!";
  for(auto &c : s)		// legal if c would not be modified
    std::cout << c << std::endl;
}

Exercise 3.12

1
2
3
4
5
6
7
int main()
{
  vector<vector<int>> ivec;	// legal, a vector object whose element is a vector object whose element is int object, first the whole vector object is empty
  vector<string> svec = ivec;	// illegal, types not match
  vector<string> svec1(10, "null"); // legal, a vector object whose elements are 10 string objects with value "null"
}

Exercise 3.13

1
2
3
4
5
6
7
8
vector<int> v1;		        // empty
vector<int> v2(10);		// 10 elements are all 0
vector<int> v3(10, 42);	        // 10 elements are all 42
vector<int> v4{10};		// 1 elements with value 10
vector<int> v5{10, 42};	        // 2 elements, first 10, second 42
vector<string> v6{10};          // 10 elements, all empty strings
vector<string> v7{10, "hi"};	// 10 elements, every one is "hi"

Exercise 3.14

1
2
3
4
5
6
7
8
int main()
{
  int i;
  vector<int> v;
  while(cin >> i)
    v.push_back(i);
}

Exercise 3.15

1
2
3
4
5
6
7
8
int main()
{
  string s;
  vector<string> v;
  while(getline(cin, s))
    v.push_back(s);
}

Exercise 3.16

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
vector<int> v1;		        // empty
vector<int> v2(10);		// 10 elements are all 0
vector<int> v3(10, 42);	        // 10 elements are all 42
vector<int> v4{10};		// 1 elements with value 10
vector<int> v5{10, 42};	        // 2 elements, first 10, second 42
vector<string> v6{10};          // 10 elements, all empty strings
vector<string> v7{10, "hi"};	// 10 elements, every one is "hi"
int main()
{
  for(auto i : v2) cout << i << endl;
  for(auto i : v3) cout << i << endl;
  for(auto i : v4) cout << i << endl;
  for(auto i : v5) cout << i << endl;
  for(auto i : v6) cout << i << endl;
  for(auto i : v7) cout << i << endl;
}

Exercise 3.17

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int main()
{
  string s;
  vector<string> v;
  while(cin >> s)
    v.push_back(s);
  for(auto &ss : v)
    {
      for(auto &c : ss)
      c = toupper(c);
    }
  for(auto ss : v)
    cout << ss << endl;
}

Exercise 3.18

1
2
3
4
5
6
7
int main()
{
  vector<int> ivec;
  // ivec[0] = 42; illegal, ivec is empty now, ivec[0] is undefinied
  ivec.push_back(42);
}

Exercise 3.19

1
2
3
4
5
6
7
8
9
int main()
{
  vector<int> v1(10, 42);	// that's better, easy to use and understand
  vector<int> v2{42, 42, 42, 42, 42, 42, 42, 42, 42, 42};
  vector<int> v3(10);
  for(unsigned i = 0; i != 10; ++i)
    v3.push_back(42);
}

Exercise 3.20

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
int main()
{
  int i;
  vector<int> v;
  while(cin >> i)
    v.push_back(i);
  for(decltype(v.size()) index = 0; index != v.size(); ++index)
    if((index + 1) < v.size())
      cout << v[index] + v[index + 1] << endl;
  for(decltype(v.size()) index = 0; index != (v.size() / 2) + 1; ++index)
    if((v.size() - 1 - index) >= index)
      cout << v[index] + v[v.size() - 1 - index] << endl;
}

Exercise 3.21

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
vector<int> v1;		        // empty
vector<int> v2(10);		// 10 elements are all 0
vector<int> v3(10, 42);	        // 10 elements are all 42
vector<int> v4{10};		// 1 elements with value 10
vector<int> v5{10, 42};	        // 2 elements, first 10, second 42
vector<string> v6{10};          // 10 elements, all empty strings
vector<string> v7{10, "hi"};	// 10 elements, every one is "hi"
int main()
{
  for(auto it = v2.begin(); it != v2.end(); ++it) cout << *it << endl;
  for(auto it = v3.begin(); it != v3.end(); ++it) cout << *it << endl;
  for(auto it = v4.begin(); it != v4.end(); ++it) cout << *it << endl;
  for(auto it = v5.begin(); it != v5.end(); ++it) cout << *it << endl;
  for(auto it = v6.begin(); it != v6.end(); ++it) cout << *it << endl;
  for(auto it = v7.begin(); it != v7.end(); ++it) cout << *it << endl;
}

Exercise 3.22

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
int main()
{
  vector<string> vs;
  string s;
  while(getline(cin, s))
    vs.push_back(s);
  for(auto it = vs.begin(); it != vs.end() && !it->empty(); ++it)
    {
      for(auto it2 = it->begin(); it2 != it->end(); ++it2)
      *it2 = toupper(*it2);
      cout << *it << endl;
    }
}

Exercise 3.23

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
int main()
{
  int i, cnt = 0;
  vector<int> v;
  while(cnt != 10 && cin >> i)
    {
      v.push_back(i);
      ++cnt;
    }
  for(auto it = v.begin(); it != v.end(); ++it)
    {
      *it = 2 * (*it);
      cout << *it << endl;
    }
}

Exercise 3.24

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
int main()
{
  int i;
  vector<int> v;
  while(cin >> i)
    v.push_back(i);
  for(auto it = v.begin(); it != v.end(); ++it)
    {
      if((it + 1) != v.end())
      cout << *it + *(it+1) << endl;
    }
  auto mid = v.begin() + v.size() / 2;
  for(auto it = v.begin(); it <= mid; ++it)
    {
      if(it <= (v.end() - (it - v.begin()) - 1)) // that is a little complicated, a better way is to define two iterator type variables in for loop, one the head, another the tail.
      cout << *it + *(v.end() - (it - v.begin()) - 1) << endl;
    }
}

Exercise 3.25

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
int main()
{
  vector<unsigned> scores(11, 0);
  unsigned grade;
  while(cin >> grade)
    {
      if(grade <= 100)
      ++(*(scores.begin() + (grade / 10)));
    }
  for(auto u : scores)
    cout << u << endl;
}

Exercise 3.26

1
2
// mid = beg + (end - beg) / 2, the type of return value of expression (end - begin) is difference_type, not iterator, that value means the number of elements between end iterator and beg iterator. (beg + end) / 2 the '+' operation between iterator type is not supported.

Exercise 3.27

1
2
3
4
5
6
7
8
9
int main()
{
  unsigned buf_size = 1024;
  int ia[buf_size];		// illegal, buf_size is not const expr
  int ia[4 * 7 - 14];		// legal, that index is const expr;
  int ia[txt_size()];		// illegal, index part is not a constexpr function
  char st[11] = "fundermental";	// illegal, space of array is not enough
}

Exercise 3.28

1
2
3
4
5
6
7
8
string sa[10];			// all elements are empty string
int ia[10];			// all elements are 0
int main()
{
  string sa2[10];		// all elements are empty string
  int ia2[10];			// all elements are undefined
}

Exercise 3.29

1
2
3
4
5
// array object's length should be settled when is is defined
// less flexibility when compared with vector, for that array object's length should keep unchanged
// it is forbidden to assign a array object ot another array object, using an array to initialize another array is not allowed, either. While vector is able to do both.
// easy to raise bugs.

Exercise 3.30

1
2
3
4
5
6
7
8
int main()
{
  constexpr size_t array_size = 10;
  int ia[array_size];
  for(size_t ix = 1; ix <= array_size; ++ix) // illegal, ix starts with 0 and should be smaller than array_size
    ia[ix] = ix;
}

Exercise 3.31

1
2
3
4
5
6
7
8
9
int main()
{
  int ia[10];
  for(size_t i = 0; i < 10; ++i)
    ia[i] = i;			// size_t type object could be implicitly converted to int type
  for(auto i : ia)
    cout << i << endl;
}

Exercise 3.32

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
  // array version
  int ia[10];
  int ib[10];
  for(size_t i = 0; i < 10; ++i)
    ia[i] = i;			// size_t type object could be implicitly converted to int type
  for(size_t i = 0; i < 10; ++i)
    ib[i] = ia[i];
  for(auto i : ib)
    cout << i << endl;
  // vector version
  vector<int> va(10);
  vector<int> vb(10);
  for(auto i = va.begin(); i != va.end(); ++i)
    *i = (i - va.begin());
  vb = va;
  for(auto i : vb)
    cout << i << endl;
}

Exercise 3.33

1
2
3
// if variable scores defined in global scope, there is a defaule initialization, it makes no difference
// else, the element of this array is undefined, ++scores[grade/10] expression wuld give unexpected result.

Exercise 3.34

1
2
3
// expression p1 += p2 - p1 makes p1 point to the object which p2 is pointing to
// that expression would be always legal for that objects pointed by p1 and p2 are in smae array.

Exercise 3.35

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
int main()
{
  int ia[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  int *pbeg = begin(ia), *pend = end(ia);
  while(pbeg != pend)
    {
      *pbeg = 0;
      ++pbeg;
    }
  for(auto i : ia)
    cout << i << endl;
}

Exercise 3.36

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int main()
{
  int ia[5] = {1, 2, 3, 4, 5};
  int ib[5] = {1, 2, 3, 4, 5};
  vector<int> va = {1, 2, 3, 4, 5};
  vector<int> vb = {1, 2, 3, 4, 5};
  auto ia_length = end(ia) - begin(ia);
  auto ib_length = end(ib) - begin(ib);
  if(ia_length != ib_length)
      cout << "array a not equals to array b" << endl;
  else
    {
      for(decltype(ia_length) index = 0; index < ia_length; ++index)
      {
	if(ia[index] != ib[index])
	  {
	    cout << "array a not equals to array b" << endl;
	    break;
	  }
      }
    }
  // vector compare
  if(va != vb) cout << "vector a not equals to vector b" << endl;
}

Exercise 3.37

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
int main()
{
  const char ca[] = {'h', 'e', 'l', 'l', 'o'};
  const char *cp = ca;		// that can do, types match
  while(*cp)			// since there is no '\0' in array ca, this while loop would repeat until '\0' encountered in ram.
    {
      cout << *cp << endl;
      ++cp;
    }

}

Exercise 3.38

1
2
// generally pointer is a ram address, there is no point in adding a pointer with another pointer, even though that operation is legal, the result is a bigger address stores something does not belong to this programming context

Exercise 3.39

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
int main()
{
  string sa = "time flys";
  string sb = "time flys my friend";
  if(sa != sb) cout << "string sa not equals to sb" << endl;
  char ca1[] = "time flys";
  char ca2[] = "time flys my friend";
  if(strcmp(ca1, ca2)) cout << "C-style character string ca1 not equals to ca2" << endl;
}

Exercise 3.40

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int main()
{
  const char ca1[] = "time flys";
  const char ca2[] = " my friend";
  const size_t new_size = strlen(ca1) + strlen(ca2) + 1;
  char ca3[new_size];
  strcpy(ca3, ca1);
  strcat(ca3, ca2);
  cout << ca3 << endl;
}

Exercise 3.41

1
2
3
4
5
6
7
8
int main()
{
  int ia[] = {0, 1, 2, 3, 4, 5};
  vector<int> v(begin(ia), end(ia));
  for(auto i : v)
    cout << i << endl;
}

Exercise 3.42

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
int main()
{
  vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
  int ia[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // this array could be initialized implictily
  for(decltype(v.size()) index = 0; index < v.size(); ++index)
    ia[index] = v[index];
  for(auto i : ia)
    cout << i << endl;
}

Exercise 3.43

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int ia[3][4] =
  {
    {0, 1, 2, 3},
    {4, 5, 6, 7},
    {8, 9, 10, 11}
  };
int main()
{
  for(int (&ib)[4] : ia)
    {
      for(int i : ib)
      cout << i << endl;
    }
  for(size_t i1 = 0; i1 != 3; ++i1)
    {
      for(size_t i2 = 0; i2 != 4; ++i2)
      cout << ia[i1][i2] << endl;
    }
  for(int (*p)[4] = ia; p != ia + 3; ++p)
    {
      for(int *q = *p; q != *p + 4; ++q)
      cout << *q << endl;
    }
}

Exercise 3.44

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using int_array = int[4];
int ia[3][4] =
  {
    {0, 1, 2, 3},
    {4, 5, 6, 7},
    {8, 9, 10, 11}
  };
int main()
{
  for(int_array &ib : ia)
    {
      for(int i : ib)
      cout << i << endl;
    }
  for(size_t i1 = 0; i1 != 3; ++i1)
    {
      for(size_t i2 = 0; i2 != 4; ++i2)
      cout << ia[i1][i2] << endl;
    }
  for(int_array *p = ia; p != ia + 3; ++p)
    {
      for(int *q = *p; q != *p + 4; ++q)
      cout << *q << endl;
    }
}

Exercise 3.45

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int ia[3][4] =
  {
    {0, 1, 2, 3},
    {4, 5, 6, 7},
    {8, 9, 10, 11}
  };
int main()
{
  for(auto &ib : ia)
    {
      for(auto i : ib)
      cout << i << endl;
    }
  for(auto i1 = 0; i1 != 3; ++i1)
    {
      for(auto i2 = 0; i2 != 4; ++i2)
      cout << ia[i1][i2] << endl;
    }
  for(auto p = ia; p != ia + 3; ++p)
    {
      for(auto q = *p; q != *p + 4; ++q)
      cout << *q << endl;
    }
}