Exercise 8.1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
istream &unlimit_inputs(istream &is)
{
  char c;
  while(!is.eof())
    {
      is >> c;
      cout << c << endl;
    }
  is.clear();
  return is;
}

Exercise 8.2

1
2
3
4
5
6
7
8
extern istream &unlimit_inputs(istream &);
int main()
{
  int i = 0;
  (unlimit_inputs(cin)) >> i;
  cout << i << endl;
}

Exercise 8.3

1
2
3
// while (cin >> i) /* ... */
// the while loop above stops when cin.fail() returns true.

Exercise 8.4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int main(int argc, char *argv[])
{
  string line;
  vector<string> vs;
  ifstream input;
  input.open(argv[argc - 1]);
  if(input)
    while(getline(input, line))
      vs.push_back(line);
  else
    cout << "Open file failed, please check the input file name!" << endl;
  for(auto &s : vs)
    cout << s << endl;
}

Exercise 8.5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
int main(int argc, char *argv[])
{
  if(argc != 2)
    {
      cout << "Incorrect command-line args, needs 2 now " << argc << endl;
      return -1;
    }
  string word;
  vector<string> vs;
  ifstream input;
  input.open(argv[argc - 1]);
  if(input)
    while(input >> word)
      vs.push_back(word);
  else
    cout << "Open file failed, please check the input file name!" << endl;
  for(auto &s : vs)
    cout << s << endl;
}

Exercise 8.6

 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
27
28
29
int main(int argc, char *argv[])
{
  if(argc != 2)
    {
      cerr << "Incorrect command-line args"
	 << " Need 2 now " << argc << endl;
      return -1;
    }
  ifstream input(argv[argc - 1]);
  Sales_data total;
  if(read(input, total))
    {
      Sales_data trans;
      while(read(input, trans))
      {
	if(total.isbn() == trans.isbn())
	  total.combine(trans);
	else
	  {
	    print(cout, total) << endl;
	    total = trans;
	  }
      }
      print(cout, total) << endl;
    }
  else
    cerr << "No data?" << endl;
}

Exercise 8.7

 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
27
28
29
30
int main(int argc, char *argv[])
{
  if(argc != 3)
    {
      cerr << "Incorrect command-line args"
	 << " Need 3 now " << argc << endl;
      return -1;
    }
  ifstream input(argv[argc - 2]);
  ofstream output(argv[argc - 1]);
  Sales_data total;
  if(read(input, total))
    {
      Sales_data trans;
      while(read(input, trans))
      {
	if(total.isbn() == trans.isbn())
	  total.combine(trans);
	else
	  {
	    print(output, total) << endl;
	    total = trans;
	  }
      }
      print(output, total) << endl;
    }
  else
    cerr << "No data?" << endl;
}

Exercise 8.8

 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
27
28
29
30
int main(int argc, char *argv[])
{
  if(argc != 3)
    {
      cerr << "Incorrect command-line args"
	 << " Need 3 now " << argc << endl;
      return -1;
    }
  ifstream input(argv[argc - 2]);
  ofstream output(argv[argc - 1], ofstream::app);
  Sales_data total;
  if(read(input, total))
    {
      Sales_data trans;
      while(read(input, trans))
      {
	if(total.isbn() == trans.isbn())
	  total.combine(trans);
	else
	  {
	    print(output, total) << endl;
	    total = trans;
	  }
      }
      print(output, total) << endl;
    }
  else
    cerr << "No data?" << endl;
}

Exercise 8.9

1
2
3
4
5
6
7
8
extern istream &unlimit_inputs(istream &is);
int main()
{
  string s = "hello world";
  istringstream is(s);
  unlimit_inputs(is);
}

Exercise 8.10

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main(int argc, char *argv[])
{
  if(argc != 2)
    {
      cerr << "Incorrect command-line args, needs 2 arguments, now "
	 << argc << endl;
      return -1;
    }
  ifstream ifs(argv[argc - 1]);
  string s, w;
  vector<string> vs;
  while(getline(ifs, s))
    vs.push_back(s);
  istringstream ist;
  for(const auto &sl : vs)
    {
      ist.str(sl);
      while(ist >> w)
      cout << w << endl;
      ist.clear();
    }
}

Exercise 8.11

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct PersonInfo
{
  string name;
  vector<string> phones;
};
int main()
{
  string line, word;
  vector<PersonInfo> people;
  istringstream record;
  while(getline(cin, line))
    {
      PersonInfo info;
      record.str(line);
      record >> info.name;
      while(record >> word)
      info.phones.push_back(word);
      people.push_back(info);
      record.clear();
    }
}

Exercise 8.12

1
2
3
// Unnecessary, synthesized default constructor would do the default initialization for us, and both two members of of this struct support default initialization.
// I think there is no relationship whith aggregate class.

Exercise 8.13

 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
struct PersonInfo
{
  string name;
  vector<string> phones;
};
int main(int argc, char *argv[])
{
  if(argc != 2)
    {
      cerr << "Incorrect command-line args, needs 2 now "
	 << argc << endl;
      return -1;
    }
  ifstream ifs(argv[argc - 1]);
  if(!ifs)
    {
      cerr << "Invalid arg " << argv[argc - 1] << endl;
      return -1;
    }
  string line, word;
  vector<PersonInfo> people;
  istringstream record;
  while(getline(ifs, line))
    {
      PersonInfo info;
      record.str(line);
      record >> info.name;
      while(record >> word)
      info.phones.push_back(word);
      people.push_back(info);
      record.clear();
    }
  for(const auto &entry : people)
    {
      ostringstream formatted, badNums;
      for(const auto &nums : entry.phones)
      {
	if(!valid(nums))
	  badNums << " " << nums;
	else
	  formatted << " " << format(nums);
      }
      if(badNums.str().empty())
      cout << entry.name << " "
	 << formatted.str() << endl;
      else
      cerr << "input error: " << entry.name
	   << " invalid number(s) " << badNums.str() << endl;
    }
}

Exercise 8.14

1
2
3
// In the context of program, there is no need to modify the two objects.
// And reference are more effective.