第十七章 标准库特殊设施 exce

练习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
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
52
53
54
55
56
#include <iostream>
#include <tuple>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <numeric>

#include "ex_17_4_SalesData.h"

using namespace std;

// matches有三个成员:1.一个书店的索引。2.指向书店中元素的迭代器。3.指向书店中元素的迭代器。
typedef tuple<vector<Sales_data>::size_type,
vector<Sales_data>::const_iterator,
vector<Sales_data>::const_iterator>
matches;

// files保存每家书店的销售记录
// findBook返回一个vector,每家销售了给定书籍的书店在其中都有一项
vector<matches> findBook(const vector<vector<Sales_data>> &files,
const string &book)
{
vector<matches> ret; //初始化为空vector
// 对每家书店,查找给定书籍匹配的记录范围
for (auto it = files.cbegin; it != files.cend(); ++it)
{
// 查找具有相同ISBN的Sales_data范围,found是一个迭代器pair
auto found = equal_range(it->cbegin(), it->cend(), book, compareIsbn);
if (found.first != found.second) // 此书店销售了给定书籍
// 记住此书店的索引及匹配的范围
ret.push_back(make_tuple(it - files.cbegin(), found.first, found.second));
}
return ret; //如果未找到匹配记录,ret为空
}

void reportResults(istream &in, ostream &os,
const vector<vector<Sales_data> > &files){
string s; //要查找的书
while (in >> s){
auto trans = findBook(files, s);
if (trans.empty()){
cout << s << " not found in any stores" << endl;
continue; // 获得下一本要查找的书
}
for (const auto &store : trans) // 对每家销售了给定书籍的书店
// get<n>返回store中tuple的指定的成员
os << "store " << get<0>(store) << " sales: "
<< accumulate(get<1>(store), get<2>(store), Sales_data(s))
<< endl;
}
}

int main(){
return 0;
}

练习17.5

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

解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
typedef std::pair<std::vector<Sales_data>::size_type,
std::pair<std::vector<Sales_data>::const_iterator,
std::vector<Sales_data>::const_iterator>>
matches_pair;

std::vector<matches_pair>
findBook_pair(const std::vector<std::vector<Sales_data> > &files,
const std::string &book)
{
std::vector<matches_pair> ret;
for(auto it = files.cbegin(); it != files.cend(); ++it)
{
auto found = std::equal_range(it->cbegin(), it->cend(), book, compareIsbn);
if(found.first != found.second)
ret.push_back(std::make_pair(it - files.cbegin(),
std::make_pair(found.first, found.second)));
}
return ret;
}

练习17.6

重写 findBook,不使用tuplepair

解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct matches_struct
{
std::vector<Sales_data>::size_type st;
std::vector<Sales_data>::const_iterator first;
std::vector<Sales_data>::const_iterator last;
matches_struct(std::vector<Sales_data>::size_type s,
std::vector<Sales_data>::const_iterator f,
std::vector<Sales_data>::const_iterator l) : st(s), first(f), last(l) { }
} ;

std::vector<matches_struct>
findBook_struct(const std::vector<std::vector<Sales_data> > &files,
const std::string &book)
{
std::vector<matches_struct> ret;
for(auto it = files.cbegin(); it != files.cend(); ++it)
{
auto found = std::equal_range(it->cbegin(), it->cend(), book, compareIsbn);
if(found.first != found.second)
ret.push_back(matches_struct(it - files.cbegin(), found.first, found.second));
}
return ret;
}

练习17.7

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

解:

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

练习17.8

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

解:

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

练习17.9

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

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

练习17.10

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

解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <bitset>
#include <vector>

int main()
{
std::vector<int> v = { 1, 2, 3, 5, 8, 13, 21 };
std::bitset<32> bset;

for (auto i : v) bset.set(i);

std::bitset<32> bset2;
for (unsigned i = 0; i != 32; ++i)
bset2[i] = bset[i];

std::cout <<bset <<std::endl;
std::cout <<bset2<<std::endl;
}

练习17.11

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

解:

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <bitset>
#include <utility>
#include <string>
#include <iostream>

//class Quiz
template<std::size_t N>
class Quiz
{
public:
//constructors
Quiz() = default;
Quiz(std::string& s) :bitquiz(s){ }

//generate grade
template<std::size_t M>
friend std::size_t grade(Quiz<M> const&, Quiz<M> const&);

//print
template<std::size_t M>
friend std::ostream& operator<<(std::ostream&, Quiz<M> const&);

//update bitset
void update(std::pair<std::size_t, bool>);
private:
std::bitset<N> bitquiz;
};
#endif

template<std::size_t N>
void Quiz<N>::update(std::pair<std::size_t, bool> pair)
{
bitquiz.set(pair.first, pair.second);
}

template<std::size_t M>
std::ostream& operator<<(std::ostream& os, Quiz<M> const& quiz)
{
os << quiz.bitquiz;
return os;
}

template<std::size_t M>
std::size_t grade(Quiz<M> const& corAns, Quiz<M> const& stuAns)
{
auto result = stuAns.bitquiz ^ corAns.bitquiz;
result.flip();
return result.count();
}

int main()
{
//Ex17_11
std::string s = "1010101";
Quiz<10> quiz(s);
std::cout << quiz << std::endl;

//EX17_12
quiz.update(std::make_pair(1, true));
std::cout << quiz << std::endl;

//Ex17_13
std::string answer = "10011";
std::string stu_answer = "11001";
Quiz<5> ans(answer), stu_ans(stu_answer);
std::cout << grade(ans, stu_ans) << std::endl;

return 0;
}

练习17.12

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

解:

参考17.11。

练习17.13

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

解:

参考17.11。

练习17.14

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

解:

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
52
53
54
55
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

#include <string>
using std::string;

#include <regex>
using std::regex;
using std::regex_error;

int main()
{
// for ex17.14
// error_brack
try{
regex r("[[:alnum:]+\\.(cpp|cxx|cc)$", regex::icase);
}
catch(regex_error e)
{
cout << e.what() << " code: " << e.code() << endl;
}

// for ex17.15
regex r("[[:alpha:]]*[^c]ei[[:alpha:]]*", regex::icase);
string s;
cout << "Please input a word! Input 'q' to quit!" << endl;
while(cin >> s && s != "q")
{
if(std::regex_match(s, r))
cout << "Input word " << s << " is okay!" << endl;
else
cout << "Input word " << s << " is not okay!" <<endl;

cout << "Please input a word! Input 'q' to quit!" << endl;
}

cout << endl;

// for ex17.16
r.assign("[^c]ei", regex::icase);
cout << "Please input a word! Input 'q' to quit!" << endl;
while(cin >> s && s != "q")
{
if(std::regex_match(s, r))
cout << "Input word " << s << " is okay!" << endl;
else
cout << "Input word " << s << " is not okay!" <<endl;

cout << "Please input a word! Input 'q' to quit!" << endl;
}

return 0;
}

练习17.15

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

解:

参考17.14。

练习17.16

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

解:

参考17.14。

练习17.17

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

解:

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
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

#include <string>
using std::string;

#include <regex>
using std::regex;
using std::sregex_iterator;

int main()
{
string s;
cout << "Please input a sequence of words:" << endl;
getline(cin, s);
cout << endl;
cout << "Word(s) that violiate the \"ei\" grammar rule:" << endl;
string pattern("[^c]ei");
pattern = "[[:alpha:]]*" + pattern + "[[:alpha:]]*";
regex r(pattern, regex::icase);
for (sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; ++it)
cout << it->str() << endl;

return 0;
}

练习17.18

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

解:

参考17.17。

练习17.19

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

解:

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

练习17.20

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

解:

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
52
53
54
55
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

#include <string>
using std::string;

#include <regex>
using std::regex;
using std::sregex_iterator;
using std::smatch;

bool valid(const smatch& m);

int main()
{
string phone = "(\\()?(\\d{ 3 })(\\))?([-. ])?(\\d{ 3 })([-. ]?)(\\d{ 4 })";
regex r(phone);
smatch m;
string s;
bool valid_record;
// read each record from the input file
while (getline(cin, s))
{
valid_record = false;
// for each matching phone number
for (sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; ++it)
{
valid_record = true;
// check whether the number's formatting is valid
if (valid(*it))
cout << "valid phone number: " << it->str() << endl;
else
cout << "invalid phone number: " << it->str() << endl;
}

if (!valid_record)
cout << "invalid record!" << endl;
}
return 0;
}

bool valid(const smatch& m)
{
// if there is an open parenthesis before the area code
if (m[1].matched)
// the area code must be followed by a close parenthesis
// and followed immediately by the rest of the number or a space
return m[3].matched && (m[4].matched == 0 || m[4].str() == " ");
else
// then there can't be a close after the area code
// the delimiters between the other two components must match
return !m[3].matched && m[4].str() == m[6].str();
}

练习17.21

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

解:

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
using std::cerr;
using std::cout;
using std::cin;
using std::endl;
using std::istream;
using std::ostream;

#include <fstream>
using std::ifstream;
using std::ofstream;

#include <sstream>
using std::istringstream;
using std::ostringstream;

#include <string>
using std::string;

#include <vector>
using std::vector;

#include <regex>
using std::regex;
using std::sregex_iterator;
using std::smatch;

struct PersonInfo
{
string name;
vector<string> phones;
};

bool valid(const smatch& m);
bool read_record(istream& is, vector<PersonInfo>& people);
void format_record(ostream& os, const vector<PersonInfo>& people);

// fake function that makes the program compile
string format(const string &num) { return num; }

int main()
{
vector<PersonInfo> people;

string filename;
cout << "Please input a record file name: ";
cin >> filename;
cout << endl;
ifstream fin(filename);

if (read_record(fin, people))
{
ofstream fout("data\\result.txt", ofstream::trunc);
format_record(fout, people);
}
else
{
cout << "Fail to open file " << filename << endl;
}

return 0;
}

bool valid(const smatch& m)
{
// if there is an open parenthesis before the area code
if (m[1].matched)
// the area code must be followed by a close parenthesis
// and followed immediately by the rest of the number or a space
return m[3].matched && (m[4].matched == 0 || m[4].str() == " ");
else
// then there can't be a close after the area code
// the delimiters between the other two components must match
return !m[3].matched && m[4].str() == m[6].str();
}

bool read_record(istream& is, vector<PersonInfo>& people)
{
if (is)
{
string line, word; // will hold a line and word from input, respectively
// read the input a line at a time until cin hits end-of-file (or another error)
while (getline(is, line))
{
PersonInfo info; // create an object to hold this record's data
istringstream record(line); // bind record to the line we just read
record >> info.name; // read the name
while (record >> word) // read the phone numbers
info.phones.push_back(word); // and store them
people.push_back(info); // append this record to people
}
return true;
}
else
return false;
}

void format_record(ostream& os, const vector<PersonInfo>& people)
{
string phone = "(\\()?(\\d{ 3 })(\\))?([-. ])?(\\d{ 3 })([-. ]?)(\\d{ 4 })";
regex r(phone);
smatch m;

for (const auto &entry : people)
{
// for each entry in people
ostringstream formatted, badNums; // objects created on each loop
for (const auto &nums : entry.phones)
{
for (sregex_iterator it(nums.begin(), nums.end(), r), end_it; it != end_it; ++it)
{
// for each number
// check whether the number's formatting is valid
if (!valid(*it))
// string in badNums
badNums << " " << nums;
else
// "writes" to formatted's string
formatted << " " << format(nums);
}
}

if (badNums.str().empty()) // there were no bad numbers
os << entry.name << " " // print the name
<< formatted.str() << endl; // and reformatted numbers
else // otherwise, print the name and bad numbers
cerr << "input error: " << entry.name
<< " invalid number(s) " << badNums.str() << endl;
}
}

练习17.22

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

解:

参考17.21。

练习17.23

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

解:

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
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

#include<string>
using std::string;

#include <regex>
using std::regex;
using std::sregex_iterator;
using std::smatch;

bool valid(const smatch& m);

int main()
{
string zipcode =
"(\\d{5})([-])?(\\d{4})?\\b";
regex r(zipcode);
smatch m;
string s;

while (getline(cin, s))
{

//! for each matching zipcode number
for (sregex_iterator it(s.begin(), s.end(), r), end_it;
it != end_it; ++it)
{
//! check whether the number's formatting is valid
if (valid(*it))
cout << "valid zipcode number: " << it->str() << endl;
else
cout << "invalid zipcode number: " << s << endl;
}

}
return 0;
}

bool valid(const smatch& m)
{

if ((m[2].matched)&&(!m[3].matched))
return false;
else
return true;
}

练习17.24

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

解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <regex>
#include <string>

using namespace std;

string pattern = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
string format = "$2.$5.$7";
regex r(pattern);
string s;

int main()
{
while(getline(cin,s))
{
cout<<regex_replace(s,r,format)<<endl;
}

return 0;
}

练习17.25

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

解:

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
#include <iostream>
#include <regex>
#include <string>

using namespace std;

string pattern = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
string fmt = "$2.$5.$7";
regex r(pattern);
string s;

int main()
{
while(getline(cin,s))
{
smatch result;
regex_search(s,result,r);
if(!result.empty())
{
cout<<result.prefix()<<result.format(fmt)<<endl;
}
else
{
cout<<"Sorry, No match."<<endl;
}
}

return 0;
}

练习17.26

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

解:

练习17.27

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

解:

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
#include <iostream>
#include <regex>
#include <string>

using namespace std;

string pattern = "(\\d{5})([.- ])?(\\d{4})";
string fmt = "$1-$3";

regex r(pattern);
string s;

int main()
{
while(getline(cin,s))
{
smatch result;
regex_search(s,result, r);

if(!result.empty())
{
cout<<result.format(fmt)<<endl;
}
else
{
cout<<"Sorry, No match."<<endl;
}

}
return 0;
}

练习17.28

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

解:

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
#include <iostream>
#include <random>
#include<string>

// default version
unsigned random_gen();
// with seed spicified
unsigned random_gen(unsigned seed);
// with seed and range spicified
unsigned random_gen(unsigned seed, unsigned min, unsigned max);
int main()
{
std::string temp;
while(std::cin >> temp)
std::cout << std::hex << random_gen(19, 1, 10) << std::endl;
return 0;
}

unsigned random_gen()
{
static std::default_random_engine e;
static std::uniform_int_distribution<unsigned> ud;
return ud(e);
}

unsigned random_gen(unsigned seed)
{
static std::default_random_engine e(seed);
static std::uniform_int_distribution<unsigned> ud;
return ud(e);
}

unsigned random_gen(unsigned seed, unsigned min, unsigned max)
{
static std::default_random_engine e(seed);
static std::uniform_int_distribution<unsigned> ud(min, max);
return ud(e);
}

练习17.29

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

解:

参考17.28。

练习17.30

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

解:

参考17.28。

练习17.31

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

解:

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

练习17.32

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

解:

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

练习17.33

修改11.3.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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
using std::cout;
using std::endl;

#include <fstream>
using std::ifstream;

#include <string>
using std::string;

#include <vector>
using std::vector;

#include <random>
using std::default_random_engine;
using std::uniform_int_distribution;

#include <ctime>
using std::time;

#include <algorithm>
using std::sort;
using std::find_if;

#include <utility>
using std::pair;

int main() {
typedef pair<string, string> ps;
ifstream i("d.txt");
vector<ps> dict;
string str1, str2;
// read wirds from dictionary
while (i >> str1 >> str2) {
dict.emplace_back(str1, str2);
}
i.close();
// sort words in vector
sort(dict.begin(), dict.end(), [](const ps &_ps1, const ps &_ps2){ return _ps1.first < _ps2.first; });
i.open("i.txt");
default_random_engine e(unsigned int(time(0)));
// read words from text
while (i >> str1) {
// find word in dictionary
vector<ps>::const_iterator it = find_if(dict.cbegin(), dict.cend(),
[&str1](const ps &_ps){ return _ps.first == str1; });
// if word doesn't exist in dictionary
if (it == dict.cend()) {
// write it itself
cout << str1 << ' ';
}
else {
// get random meaning of word
uniform_int_distribution<unsigned> u (0, find_if(dict.cbegin(), dict.cend(),
[&str1](const ps &_ps){ return _ps.first > str1; }) - it - 1);
// write random meaning
cout << (it + u(e))->second << ' ';
}
}

return 0;
}

练习17.34

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

解:

练习17.35

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

解:

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

#include <iostream>
#include<iomanip>
#include <math.h>
using namespace std;

int main()
{
cout <<"default format: " << 100 * sqrt(2.0) << '\n'
<< "scientific: " << scientific << 100 * sqrt(2.0) << '\n'
<< "fixed decimal: " << fixed << 100 * sqrt(2.0) << '\n'
<< "hexidecimal: " << uppercase << hexfloat << 100 * sqrt(2.0) << '\n'
<< "use defaults: " << defaultfloat << 100 * sqrt(2.0)
<< "\n\n";
}

//17.36
//Modify the program from the previous exercise to print the various floating-point values so that they line up in a column.
#include <iostream>
#include<iomanip>
#include <math.h>
using namespace std;

int main()
{
cout <<left<<setw(15) << "default format:" <<setw(25)<< right<< 100 * sqrt(2.0) << '\n'
<< left << setw(15) << "scientific:" << scientific << setw(25) << right << 100 * sqrt(2.0) << '\n'
<< left << setw(15) << "fixed decimal:" << setw(25) << fixed << right << 100 * sqrt(2.0) << '\n'
<< left << setw(15) << "hexidecimal:" << setw(25) << uppercase << hexfloat << right << 100 * sqrt(2.0) << '\n'
<< left << setw(15) << "use defaults:" << setw(25) << defaultfloat << right << 100 * sqrt(2.0)
<< "\n\n";
}

练习17.36

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

解:

参考17.36。

练习17.37

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

解:

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
//17.37
//Use the unformatted version of getline to read a file a line at a time.
//Test your program by giving it a file that contains empty lines as well as lines that are
//longer than the character array that you pass to getline.

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

//int main () {
// ifstream myfile("F:\\Git\\Cpp-Primer\\ch17\\17_37_38\\test.txt");
// if (myfile) cout << 1 << endl;
// char sink [250];
//
// while(myfile.getline(sink,250))
// {
// cout << sink << endl;
// }
// return 0;
//}

//17.38
//Extend your program from the previous exercise to print each word you read onto its own line.

//#include <iostream>
//#include <fstream>
//#include <iomanip>
//
//using namespace std;
//
//int main () {
// ifstream myfile ("F:\\Git\\Cpp-Primer\\ch17\\17_37_38\\test.txt");
// char sink [250];
//
// while(myfile.getline(sink,250,' '))
// {
// cout << sink << endl;
// }
// return 0;
//}

int main()
{
std::cout << "Standard Output!\n";
std::cerr << "Standard Error!\n";
std::clog << "Standard Log??\n";
}

练习17.38

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

解:

参考17.37。

练习17.39

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

解: