练习17.1

定义一个保存三个int值的 tuple,并将其成员分别初始化为10、20和30。

解:

  1. auto t = tuple<int, int, int>{10, 20, 30};

练习17.2

定义一个 tuple,保存一个 string、一个vector<string> 和一个 pair<string, int>

解:

  1. auto t = tuple<string, vector<string>, pair<string, int> >

练习17.3

重写12.3节中的 TextQuery 程序,使用 tuple 代替 QueryResult 类。你认为哪种设计更好?为什么?

解:

程序略。

我认为tuple更方便。

练习17.4

编写并测试你自己版本的 findBook 函数。

解:

  1. #include <iostream>
  2. #include <tuple>
  3. #include <string>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <utility>
  7. #include <numeric>
  8. #include "ex_17_4_SalesData.h"
  9. using namespace std;
  10. // matches有三个成员:1.一个书店的索引。2.指向书店中元素的迭代器。3.指向书店中元素的迭代器。
  11. typedef tuple<vector<Sales_data>::size_type,
  12. vector<Sales_data>::const_iterator,
  13. vector<Sales_data>::const_iterator>
  14. matches;
  15. // files保存每家书店的销售记录
  16. // findBook返回一个vector,每家销售了给定书籍的书店在其中都有一项
  17. vector<matches> findBook(const vector<vector<Sales_data>> &files,
  18. const string &book)
  19. {
  20. vector<matches> ret; //初始化为空vector
  21. // 对每家书店,查找给定书籍匹配的记录范围
  22. for (auto it = files.cbegin; it != files.cend(); ++it)
  23. {
  24. // 查找具有相同ISBN的Sales_data范围,found是一个迭代器pair
  25. auto found = equal_range(it->cbegin(), it->cend(), book, compareIsbn);
  26. if (found.first != found.second) // 此书店销售了给定书籍
  27. // 记住此书店的索引及匹配的范围
  28. ret.push_back(make_tuple(it - files.cbegin(), found.first, found.second));
  29. }
  30. return ret; //如果未找到匹配记录,ret为空
  31. }
  32. void reportResults(istream &in, ostream &os,
  33. const vector<vector<Sales_data> > &files){
  34. string s; //要查找的书
  35. while (in >> s){
  36. auto trans = findBook(files, s);
  37. if (trans.empty()){
  38. cout << s << " not found in any stores" << endl;
  39. continue; // 获得下一本要查找的书
  40. }
  41. for (const auto &store : trans) // 对每家销售了给定书籍的书店
  42. // get<n>返回store中tuple的指定的成员
  43. os << "store " << get<0>(store) << " sales: "
  44. << accumulate(get<1>(store), get<2>(store), Sales_data(s))
  45. << endl;
  46. }
  47. }
  48. int main(){
  49. return 0;
  50. }

练习17.5

重写 findBook,令其返回一个 pair,包含一个索引和一个迭代器pair。

解:

  1. typedef std::pair<std::vector<Sales_data>::size_type,
  2. std::pair<std::vector<Sales_data>::const_iterator,
  3. std::vector<Sales_data>::const_iterator>>
  4. matches_pair;
  5. std::vector<matches_pair>
  6. findBook_pair(const std::vector<std::vector<Sales_data> > &files,
  7. const std::string &book)
  8. {
  9. std::vector<matches_pair> ret;
  10. for(auto it = files.cbegin(); it != files.cend(); ++it)
  11. {
  12. auto found = std::equal_range(it->cbegin(), it->cend(), book, compareIsbn);
  13. if(found.first != found.second)
  14. ret.push_back(std::make_pair(it - files.cbegin(),
  15. std::make_pair(found.first, found.second)));
  16. }
  17. return ret;
  18. }

练习17.6

重写 findBook,不使用tuplepair

解:

  1. struct matches_struct
  2. {
  3. std::vector<Sales_data>::size_type st;
  4. std::vector<Sales_data>::const_iterator first;
  5. std::vector<Sales_data>::const_iterator last;
  6. matches_struct(std::vector<Sales_data>::size_type s,
  7. std::vector<Sales_data>::const_iterator f,
  8. std::vector<Sales_data>::const_iterator l) : st(s), first(f), last(l) { }
  9. } ;
  10. std::vector<matches_struct>
  11. findBook_struct(const std::vector<std::vector<Sales_data> > &files,
  12. const std::string &book)
  13. {
  14. std::vector<matches_struct> ret;
  15. for(auto it = files.cbegin(); it != files.cend(); ++it)
  16. {
  17. auto found = std::equal_range(it->cbegin(), it->cend(), book, compareIsbn);
  18. if(found.first != found.second)
  19. ret.push_back(matches_struct(it - files.cbegin(), found.first, found.second));
  20. }
  21. return ret;
  22. }

练习17.7

解释你更倾向于哪个版本的findBook,为什么。

解:

使用tuple的版本。很明显更加灵活方便。

练习17.8

在本节最后一段代码中,如果我们将Sales_data()作为第三个参数传递给accumulate,会发生什么?

解:

结果是0,以为Sales_data是默认初始化的。

练习17.9

解释下列每个bitset 对象所包含的位模式:

  1. (a) bitset<64> bitvec(32);
  2. // 0000000000000000000000000000000000000000000000000000000000100000
  3. (b) bitset<32> bv(1010101);
  4. // 00000000000011110110100110110101
  5. (c) string bstr; cin >> bstr; bitset<8> bv(bstr);
  6. // 根据输入的str转换成bitset

练习17.10

使用序列1、2、3、5、8、13、21初始化一个bitset,将这些位置置位。对另一个bitset进行默认初始化,并编写一小段程序将其恰当的位置位。

解:

  1. #include <iostream>
  2. #include <bitset>
  3. #include <vector>
  4. int main()
  5. {
  6. std::vector<int> v = { 1, 2, 3, 5, 8, 13, 21 };
  7. std::bitset<32> bset;
  8. for (auto i : v) bset.set(i);
  9. std::bitset<32> bset2;
  10. for (unsigned i = 0; i != 32; ++i)
  11. bset2[i] = bset[i];
  12. std::cout <<bset <<std::endl;
  13. std::cout <<bset2<<std::endl;
  14. }

练习17.11

定义一个数据结构,包含一个整型对象,记录一个包含10个问题的真/假测验的解答。如果测验包含100道题,你需要对数据结构做出什么改变(如果需要的话)?

解:

  1. #include <iostream>
  2. #include <bitset>
  3. #include <utility>
  4. #include <string>
  5. #include <iostream>
  6. //class Quiz
  7. template<std::size_t N>
  8. class Quiz
  9. {
  10. public:
  11. //constructors
  12. Quiz() = default;
  13. Quiz(std::string& s) :bitquiz(s){ }
  14. //generate grade
  15. template<std::size_t M>
  16. friend std::size_t grade(Quiz<M> const&, Quiz<M> const&);
  17. //print
  18. template<std::size_t M>
  19. friend std::ostream& operator<<(std::ostream&, Quiz<M> const&);
  20. //update bitset
  21. void update(std::pair<std::size_t, bool>);
  22. private:
  23. std::bitset<N> bitquiz;
  24. };
  25. #endif
  26. template<std::size_t N>
  27. void Quiz<N>::update(std::pair<std::size_t, bool> pair)
  28. {
  29. bitquiz.set(pair.first, pair.second);
  30. }
  31. template<std::size_t M>
  32. std::ostream& operator<<(std::ostream& os, Quiz<M> const& quiz)
  33. {
  34. os << quiz.bitquiz;
  35. return os;
  36. }
  37. template<std::size_t M>
  38. std::size_t grade(Quiz<M> const& corAns, Quiz<M> const& stuAns)
  39. {
  40. auto result = stuAns.bitquiz ^ corAns.bitquiz;
  41. result.flip();
  42. return result.count();
  43. }
  44. int main()
  45. {
  46. //Ex17_11
  47. std::string s = "1010101";
  48. Quiz<10> quiz(s);
  49. std::cout << quiz << std::endl;
  50. //EX17_12
  51. quiz.update(std::make_pair(1, true));
  52. std::cout << quiz << std::endl;
  53. //Ex17_13
  54. std::string answer = "10011";
  55. std::string stu_answer = "11001";
  56. Quiz<5> ans(answer), stu_ans(stu_answer);
  57. std::cout << grade(ans, stu_ans) << std::endl;
  58. return 0;
  59. }

练习17.12

使用前一题中的数据结构,编写一个函数,它接受一个问题编号和一个表示真/假解答的值,函数根据这两个参数更新测验的解答。

解:

参考17.11。

练习17.13

编写一个整型对象,包含真/假测验的正确答案。使用它来为前两题中的数据结构生成测验成绩。

解:

参考17.11。

练习17.14

编写几个正则表达式,分别触发不同错误。运行你的程序,观察编译器对每个错误的输出。

解:

  1. #include <iostream>
  2. using std::cout;
  3. using std::cin;
  4. using std::endl;
  5. #include <string>
  6. using std::string;
  7. #include <regex>
  8. using std::regex;
  9. using std::regex_error;
  10. int main()
  11. {
  12. // for ex17.14
  13. // error_brack
  14. try{
  15. regex r("[[:alnum:]+\\.(cpp|cxx|cc)$", regex::icase);
  16. }
  17. catch(regex_error e)
  18. {
  19. cout << e.what() << " code: " << e.code() << endl;
  20. }
  21. // for ex17.15
  22. regex r("[[:alpha:]]*[^c]ei[[:alpha:]]*", regex::icase);
  23. string s;
  24. cout << "Please input a word! Input 'q' to quit!" << endl;
  25. while(cin >> s && s != "q")
  26. {
  27. if(std::regex_match(s, r))
  28. cout << "Input word " << s << " is okay!" << endl;
  29. else
  30. cout << "Input word " << s << " is not okay!" <<endl;
  31. cout << "Please input a word! Input 'q' to quit!" << endl;
  32. }
  33. cout << endl;
  34. // for ex17.16
  35. r.assign("[^c]ei", regex::icase);
  36. cout << "Please input a word! Input 'q' to quit!" << endl;
  37. while(cin >> s && s != "q")
  38. {
  39. if(std::regex_match(s, r))
  40. cout << "Input word " << s << " is okay!" << endl;
  41. else
  42. cout << "Input word " << s << " is not okay!" <<endl;
  43. cout << "Please input a word! Input 'q' to quit!" << endl;
  44. }
  45. return 0;
  46. }

练习17.15

编写程序,使用模式查找违反“i在e之前,除非在c之后”规则的单词。你的程序应该提示用户输入一个单词,然后指出此单词是否符号要求。用一些违反和未违反规则的单词测试你的程序。

解:

参考17.14。

练习17.16

如果前一题程序中的regex对象用"[^c]ei"进行初始化,将会发生什么?用此模式测试你的程序,检查你的答案是否正确。

解:

参考17.14。

练习17.17

更新你的程序,令它查找输入序列中所有违反”ei”语法规则的单词。

解:

  1. #include <iostream>
  2. using std::cout;
  3. using std::cin;
  4. using std::endl;
  5. #include <string>
  6. using std::string;
  7. #include <regex>
  8. using std::regex;
  9. using std::sregex_iterator;
  10. int main()
  11. {
  12. string s;
  13. cout << "Please input a sequence of words:" << endl;
  14. getline(cin, s);
  15. cout << endl;
  16. cout << "Word(s) that violiate the \"ei\" grammar rule:" << endl;
  17. string pattern("[^c]ei");
  18. pattern = "[[:alpha:]]*" + pattern + "[[:alpha:]]*";
  19. regex r(pattern, regex::icase);
  20. for (sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; ++it)
  21. cout << it->str() << endl;
  22. return 0;
  23. }

练习17.18

修改你的程序,忽略包含“ei`但并非拼写错误的单词,如“albeit”和“neighbor”。

解:

参考17.17。

练习17.19

为什么可以不先检查m[4]是否匹配了就直接调用m[4].str()

解:

如果不匹配,则m[4].str()返回空字符串。

练习17.20

编写你自己版本的验证电话号码的程序。

解:

  1. #include <iostream>
  2. using std::cout;
  3. using std::cin;
  4. using std::endl;
  5. #include <string>
  6. using std::string;
  7. #include <regex>
  8. using std::regex;
  9. using std::sregex_iterator;
  10. using std::smatch;
  11. bool valid(const smatch& m);
  12. int main()
  13. {
  14. string phone = "(\\()?(\\d{ 3 })(\\))?([-. ])?(\\d{ 3 })([-. ]?)(\\d{ 4 })";
  15. regex r(phone);
  16. smatch m;
  17. string s;
  18. bool valid_record;
  19. // read each record from the input file
  20. while (getline(cin, s))
  21. {
  22. valid_record = false;
  23. // for each matching phone number
  24. for (sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; ++it)
  25. {
  26. valid_record = true;
  27. // check whether the number's formatting is valid
  28. if (valid(*it))
  29. cout << "valid phone number: " << it->str() << endl;
  30. else
  31. cout << "invalid phone number: " << it->str() << endl;
  32. }
  33. if (!valid_record)
  34. cout << "invalid record!" << endl;
  35. }
  36. return 0;
  37. }
  38. bool valid(const smatch& m)
  39. {
  40. // if there is an open parenthesis before the area code
  41. if (m[1].matched)
  42. // the area code must be followed by a close parenthesis
  43. // and followed immediately by the rest of the number or a space
  44. return m[3].matched && (m[4].matched == 0 || m[4].str() == " ");
  45. else
  46. // then there can't be a close after the area code
  47. // the delimiters between the other two components must match
  48. return !m[3].matched && m[4].str() == m[6].str();
  49. }

练习17.21

使用本节定义的valid 函数重写8.3.2节中的电话号码程序。

解:

  1. #include <iostream>
  2. using std::cerr;
  3. using std::cout;
  4. using std::cin;
  5. using std::endl;
  6. using std::istream;
  7. using std::ostream;
  8. #include <fstream>
  9. using std::ifstream;
  10. using std::ofstream;
  11. #include <sstream>
  12. using std::istringstream;
  13. using std::ostringstream;
  14. #include <string>
  15. using std::string;
  16. #include <vector>
  17. using std::vector;
  18. #include <regex>
  19. using std::regex;
  20. using std::sregex_iterator;
  21. using std::smatch;
  22. struct PersonInfo
  23. {
  24. string name;
  25. vector<string> phones;
  26. };
  27. bool valid(const smatch& m);
  28. bool read_record(istream& is, vector<PersonInfo>& people);
  29. void format_record(ostream& os, const vector<PersonInfo>& people);
  30. // fake function that makes the program compile
  31. string format(const string &num) { return num; }
  32. int main()
  33. {
  34. vector<PersonInfo> people;
  35. string filename;
  36. cout << "Please input a record file name: ";
  37. cin >> filename;
  38. cout << endl;
  39. ifstream fin(filename);
  40. if (read_record(fin, people))
  41. {
  42. ofstream fout("data\\result.txt", ofstream::trunc);
  43. format_record(fout, people);
  44. }
  45. else
  46. {
  47. cout << "Fail to open file " << filename << endl;
  48. }
  49. return 0;
  50. }
  51. bool valid(const smatch& m)
  52. {
  53. // if there is an open parenthesis before the area code
  54. if (m[1].matched)
  55. // the area code must be followed by a close parenthesis
  56. // and followed immediately by the rest of the number or a space
  57. return m[3].matched && (m[4].matched == 0 || m[4].str() == " ");
  58. else
  59. // then there can't be a close after the area code
  60. // the delimiters between the other two components must match
  61. return !m[3].matched && m[4].str() == m[6].str();
  62. }
  63. bool read_record(istream& is, vector<PersonInfo>& people)
  64. {
  65. if (is)
  66. {
  67. string line, word; // will hold a line and word from input, respectively
  68. // read the input a line at a time until cin hits end-of-file (or another error)
  69. while (getline(is, line))
  70. {
  71. PersonInfo info; // create an object to hold this record's data
  72. istringstream record(line); // bind record to the line we just read
  73. record >> info.name; // read the name
  74. while (record >> word) // read the phone numbers
  75. info.phones.push_back(word); // and store them
  76. people.push_back(info); // append this record to people
  77. }
  78. return true;
  79. }
  80. else
  81. return false;
  82. }
  83. void format_record(ostream& os, const vector<PersonInfo>& people)
  84. {
  85. string phone = "(\\()?(\\d{ 3 })(\\))?([-. ])?(\\d{ 3 })([-. ]?)(\\d{ 4 })";
  86. regex r(phone);
  87. smatch m;
  88. for (const auto &entry : people)
  89. {
  90. // for each entry in people
  91. ostringstream formatted, badNums; // objects created on each loop
  92. for (const auto &nums : entry.phones)
  93. {
  94. for (sregex_iterator it(nums.begin(), nums.end(), r), end_it; it != end_it; ++it)
  95. {
  96. // for each number
  97. // check whether the number's formatting is valid
  98. if (!valid(*it))
  99. // string in badNums
  100. badNums << " " << nums;
  101. else
  102. // "writes" to formatted's string
  103. formatted << " " << format(nums);
  104. }
  105. }
  106. if (badNums.str().empty()) // there were no bad numbers
  107. os << entry.name << " " // print the name
  108. << formatted.str() << endl; // and reformatted numbers
  109. else // otherwise, print the name and bad numbers
  110. cerr << "input error: " << entry.name
  111. << " invalid number(s) " << badNums.str() << endl;
  112. }
  113. }

练习17.22

重写你的电话号码程序,使之允许在号码的三个部分之间放置任意多个空白符。

解:

参考17.21。

练习17.23

编写查找邮政编码的正则表达式。一个美国邮政编码可以由五位或九位数字组成。前五位数字和后四位数字之间可以用一个短横线分隔。

解:

  1. #include <iostream>
  2. using std::cout;
  3. using std::cin;
  4. using std::endl;
  5. #include<string>
  6. using std::string;
  7. #include <regex>
  8. using std::regex;
  9. using std::sregex_iterator;
  10. using std::smatch;
  11. bool valid(const smatch& m);
  12. int main()
  13. {
  14. string zipcode =
  15. "(\\d{5})([-])?(\\d{4})?\\b";
  16. regex r(zipcode);
  17. smatch m;
  18. string s;
  19. while (getline(cin, s))
  20. {
  21. //! for each matching zipcode number
  22. for (sregex_iterator it(s.begin(), s.end(), r), end_it;
  23. it != end_it; ++it)
  24. {
  25. //! check whether the number's formatting is valid
  26. if (valid(*it))
  27. cout << "valid zipcode number: " << it->str() << endl;
  28. else
  29. cout << "invalid zipcode number: " << s << endl;
  30. }
  31. }
  32. return 0;
  33. }
  34. bool valid(const smatch& m)
  35. {
  36. if ((m[2].matched)&&(!m[3].matched))
  37. return false;
  38. else
  39. return true;
  40. }

练习17.24

编写你自己版本的重拍电话号码格式的程序。

解:

  1. #include <iostream>
  2. #include <regex>
  3. #include <string>
  4. using namespace std;
  5. string pattern = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
  6. string format = "$2.$5.$7";
  7. regex r(pattern);
  8. string s;
  9. int main()
  10. {
  11. while(getline(cin,s))
  12. {
  13. cout<<regex_replace(s,r,format)<<endl;
  14. }
  15. return 0;
  16. }

练习17.25

重写你的电话号码程序,使之只输出每个人的第一个电话号码。

解:

  1. #include <iostream>
  2. #include <regex>
  3. #include <string>
  4. using namespace std;
  5. string pattern = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
  6. string fmt = "$2.$5.$7";
  7. regex r(pattern);
  8. string s;
  9. int main()
  10. {
  11. while(getline(cin,s))
  12. {
  13. smatch result;
  14. regex_search(s,result,r);
  15. if(!result.empty())
  16. {
  17. cout<<result.prefix()<<result.format(fmt)<<endl;
  18. }
  19. else
  20. {
  21. cout<<"Sorry, No match."<<endl;
  22. }
  23. }
  24. return 0;
  25. }

练习17.26

重写你的电话号码程序,使之对多于一个电话号码的人只输出第二个和后续号码。

解:

练习17.27

编写程序,将九位数字邮政编码的格式转换为 ddddd-dddd

解:

  1. #include <iostream>
  2. #include <regex>
  3. #include <string>
  4. using namespace std;
  5. string pattern = "(\\d{5})([.- ])?(\\d{4})";
  6. string fmt = "$1-$3";
  7. regex r(pattern);
  8. string s;
  9. int main()
  10. {
  11. while(getline(cin,s))
  12. {
  13. smatch result;
  14. regex_search(s,result, r);
  15. if(!result.empty())
  16. {
  17. cout<<result.format(fmt)<<endl;
  18. }
  19. else
  20. {
  21. cout<<"Sorry, No match."<<endl;
  22. }
  23. }
  24. return 0;
  25. }

练习17.28

编写函数,每次调用生成并返回一个均匀分布的随机unsigned int

解:

  1. #include <iostream>
  2. #include <random>
  3. #include<string>
  4. // default version
  5. unsigned random_gen();
  6. // with seed spicified
  7. unsigned random_gen(unsigned seed);
  8. // with seed and range spicified
  9. unsigned random_gen(unsigned seed, unsigned min, unsigned max);
  10. int main()
  11. {
  12. std::string temp;
  13. while(std::cin >> temp)
  14. std::cout << std::hex << random_gen(19, 1, 10) << std::endl;
  15. return 0;
  16. }
  17. unsigned random_gen()
  18. {
  19. static std::default_random_engine e;
  20. static std::uniform_int_distribution<unsigned> ud;
  21. return ud(e);
  22. }
  23. unsigned random_gen(unsigned seed)
  24. {
  25. static std::default_random_engine e(seed);
  26. static std::uniform_int_distribution<unsigned> ud;
  27. return ud(e);
  28. }
  29. unsigned random_gen(unsigned seed, unsigned min, unsigned max)
  30. {
  31. static std::default_random_engine e(seed);
  32. static std::uniform_int_distribution<unsigned> ud(min, max);
  33. return ud(e);
  34. }

练习17.29

修改上一题中编写的函数,允许用户提供一个种子作为可选参数。

解:

参考17.28。

练习17.30

再次修改你的程序,此次增加两个参数,表示函数允许返回的最小值和最大值。

解:

参考17.28。

练习17.31

对于本节中的游戏程序,如果在do循环内定义be,会发生什么?

解:

由于引擎返回相同的随机数序列,因此眉不循环都会创建新的引擎,眉不循环都会生成相同的值。

练习17.32

如果我们在循环内定义resp,会发生什么?

解:

会报错,while条件中用到了resp

练习17.33

修改11.3.6节中的单词转换程序,允许对一个给定单词有多种转换方式,每次随机选择一种进行实际转换。

解:

  1. #include <iostream>
  2. using std::cout;
  3. using std::endl;
  4. #include <fstream>
  5. using std::ifstream;
  6. #include <string>
  7. using std::string;
  8. #include <vector>
  9. using std::vector;
  10. #include <random>
  11. using std::default_random_engine;
  12. using std::uniform_int_distribution;
  13. #include <ctime>
  14. using std::time;
  15. #include <algorithm>
  16. using std::sort;
  17. using std::find_if;
  18. #include <utility>
  19. using std::pair;
  20. int main() {
  21. typedef pair<string, string> ps;
  22. ifstream i("d.txt");
  23. vector<ps> dict;
  24. string str1, str2;
  25. // read wirds from dictionary
  26. while (i >> str1 >> str2) {
  27. dict.emplace_back(str1, str2);
  28. }
  29. i.close();
  30. // sort words in vector
  31. sort(dict.begin(), dict.end(), [](const ps &_ps1, const ps &_ps2){ return _ps1.first < _ps2.first; });
  32. i.open("i.txt");
  33. default_random_engine e(unsigned int(time(0)));
  34. // read words from text
  35. while (i >> str1) {
  36. // find word in dictionary
  37. vector<ps>::const_iterator it = find_if(dict.cbegin(), dict.cend(),
  38. [&str1](const ps &_ps){ return _ps.first == str1; });
  39. // if word doesn't exist in dictionary
  40. if (it == dict.cend()) {
  41. // write it itself
  42. cout << str1 << ' ';
  43. }
  44. else {
  45. // get random meaning of word
  46. uniform_int_distribution<unsigned> u (0, find_if(dict.cbegin(), dict.cend(),
  47. [&str1](const ps &_ps){ return _ps.first > str1; }) - it - 1);
  48. // write random meaning
  49. cout << (it + u(e))->second << ' ';
  50. }
  51. }
  52. return 0;
  53. }

练习17.34

编写一个程序,展示如何使用表17.17和表17.18中的每个操作符。

解:

练习17.35

修改第670页中的程序,打印2的平方根,但这次打印十六进制数字的大写形式。

解:

  1. #include <iostream>
  2. #include<iomanip>
  3. #include <math.h>
  4. using namespace std;
  5. int main()
  6. {
  7. cout <<"default format: " << 100 * sqrt(2.0) << '\n'
  8. << "scientific: " << scientific << 100 * sqrt(2.0) << '\n'
  9. << "fixed decimal: " << fixed << 100 * sqrt(2.0) << '\n'
  10. << "hexidecimal: " << uppercase << hexfloat << 100 * sqrt(2.0) << '\n'
  11. << "use defaults: " << defaultfloat << 100 * sqrt(2.0)
  12. << "\n\n";
  13. }
  14. //17.36
  15. //Modify the program from the previous exercise to print the various floating-point values so that they line up in a column.
  16. #include <iostream>
  17. #include<iomanip>
  18. #include <math.h>
  19. using namespace std;
  20. int main()
  21. {
  22. cout <<left<<setw(15) << "default format:" <<setw(25)<< right<< 100 * sqrt(2.0) << '\n'
  23. << left << setw(15) << "scientific:" << scientific << setw(25) << right << 100 * sqrt(2.0) << '\n'
  24. << left << setw(15) << "fixed decimal:" << setw(25) << fixed << right << 100 * sqrt(2.0) << '\n'
  25. << left << setw(15) << "hexidecimal:" << setw(25) << uppercase << hexfloat << right << 100 * sqrt(2.0) << '\n'
  26. << left << setw(15) << "use defaults:" << setw(25) << defaultfloat << right << 100 * sqrt(2.0)
  27. << "\n\n";
  28. }

练习17.36

修改上一题中的程序,打印不同的浮点数,使它们排成一列。

解:

参考17.36。

练习17.37

用未格式化版本的getline 逐行读取一个文件。测试你的程序,给定一个文件,既包含空行又包含长度超过你传递给geiline的字符数组大小的行。

解:

  1. //17.37
  2. //Use the unformatted version of getline to read a file a line at a time.
  3. //Test your program by giving it a file that contains empty lines as well as lines that are
  4. //longer than the character array that you pass to getline.
  5. #include <iostream>
  6. #include <fstream>
  7. #include <iomanip>
  8. using namespace std;
  9. //int main () {
  10. // ifstream myfile("F:\\Git\\Cpp-Primer\\ch17\\17_37_38\\test.txt");
  11. // if (myfile) cout << 1 << endl;
  12. // char sink [250];
  13. //
  14. // while(myfile.getline(sink,250))
  15. // {
  16. // cout << sink << endl;
  17. // }
  18. // return 0;
  19. //}
  20. //17.38
  21. //Extend your program from the previous exercise to print each word you read onto its own line.
  22. //#include <iostream>
  23. //#include <fstream>
  24. //#include <iomanip>
  25. //
  26. //using namespace std;
  27. //
  28. //int main () {
  29. // ifstream myfile ("F:\\Git\\Cpp-Primer\\ch17\\17_37_38\\test.txt");
  30. // char sink [250];
  31. //
  32. // while(myfile.getline(sink,250,' '))
  33. // {
  34. // cout << sink << endl;
  35. // }
  36. // return 0;
  37. //}
  38. int main()
  39. {
  40. std::cout << "Standard Output!\n";
  41. std::cerr << "Standard Error!\n";
  42. std::clog << "Standard Log??\n";
  43. }

练习17.38

扩展上一题中你的程序,将读入的每个单词打印到它所在的行。

解:

参考17.37。

练习17.39

对本节给出的 seek程序,编写你自己的版本。

解: