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 | // Please write a program that displays times tables in C++.
#include <iostream>
#include <string>
#include <sstream>
std::string ToString(int n)
{
std::stringstream stream;
std::string result;
stream << n;
stream >> result;
return result;
}
class TimesTable
{
public:
TimesTable();
TimesTable(int x, int y, int padding = 1);
void Render(std::ostream& s, bool perspective = false);
private:
void SetStreamState(std::ostream& s);
void RevertStreamState(std::ostream& s);
void RenderImpl(std::ostream& s, bool perspective);
void RenderItem(std::ostream& s, int item);
int m_x, m_y;
int m_longest;
int m_padding;
std::ios_base::fmtflags m_stream_flags;
};
TimesTable::TimesTable()
: m_x(12)
, m_y(12)
, m_padding(1)
, m_longest(ToString(12 * 12).size())
{
}
TimesTable::TimesTable(int x, int y, int padding)
: m_x(x)
, m_y(y)
, m_padding(padding)
, m_longest(ToString(x * y).size())
{
}
void TimesTable::Render(std::ostream& s, bool perspective)
{
SetStreamState(s);
try
{
RenderImpl(s, perspective);
}
catch (...)
{
RevertStreamState(s);
throw;
}
RevertStreamState(s);
}
void TimesTable::RenderImpl(std::ostream& s, bool perspective)
{
s << std::endl;
for (int y = 1; y <= m_y; ++y)
{
if (perspective)
m_padding++;
RenderItem(s, y);
for (int x = 1; x <= m_x; ++x)
RenderItem(s, x * y);
s << std::endl;
}
s << std::endl;
}
void TimesTable::SetStreamState(std::ostream& s)
{
m_stream_flags = s.flags();
s.setf(std::ios_base::right, std::ios_base::adjustfield);
}
void TimesTable::RevertStreamState(std::ostream& s)
{
s.setf(m_stream_flags);
}
void TimesTable::RenderItem(std::ostream& s, int item)
{
s.width(m_longest + m_padding);
s << ToString(item);
}
int main(int argc, char** argv)
{
TimesTable t(9, 9);
t.Render(std::cout);
t.Render(std::cout, true);
return 0;
}
|