Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2bb0c9a

Browse files
committed
Exercise 23.11; Exercise 23.12
1 parent 58f487e commit 2bb0c9a

File tree

5 files changed

+402
-0
lines changed

5 files changed

+402
-0
lines changed

‎Chapter_23/C23_Exercise_23.11.cpp

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/* Exercise 23.11 */
2+
3+
#include<iostream>
4+
#include<istream>
5+
#include<fstream>
6+
#include<sstream>
7+
#include<iomanip>
8+
#include<string>
9+
#include<vector>
10+
#include<map>
11+
#include<regex>
12+
#include"C23_Exercise_23.11.h"
13+
14+
using namespace std;
15+
16+
inline void error(string s) { throw runtime_error(s); }
17+
inline void error(const string& s, const string& s2) { error(s + s2); }
18+
inline void error(const string& s, int i) { ostringstream os; os << s << ": " << i; error(os.str()); }
19+
inline void keep_window_open() { char ch; cin >> ch; }
20+
21+
int main()
22+
{
23+
enum Action {
24+
EXIT = -1, PRINTACTIONLIST,
25+
CASE1, CASE2, CASE3, CASE4, CASE5
26+
};
27+
const string actionList = "\tList of actions:\n"
28+
" (1) Number of students\n"
29+
" (-1) Exit, (0) Print the list of actions\n";
30+
cout << actionList;
31+
int action;
32+
bool cond{ true };
33+
while (cond) try {
34+
cout << "\nPlease enter the action: ";
35+
if (!(cin >> action)) { ClearInput(cin); error("Error. Incorrect input"); }
36+
char ch;
37+
cin.get(ch);
38+
switch (action) {
39+
case CASE1: {
40+
cout << endl;
41+
ifstream ifs{ "C23_Exercise_23.9_table.txt" };
42+
if (!ifs) error("Error. File opening error");
43+
ofstream ofs{ "C23_Exercise_23.11_table_students.txt" };
44+
if (!ofs) error("Error. File opening error");
45+
string first;
46+
size_t lineNum = 0;
47+
regex header{ R"(^[\w ]+(\t[\w ]+)*$)" }; // header line
48+
regex row{ R"(^([\w ]+)(\t\d+)(\t\d+)(\t\d+)$)" }; // data line
49+
50+
if (getline(ifs, first)) { // check header line
51+
smatch matches;
52+
if (!regex_match(first, matches, header)) {
53+
error("Error. No header");
54+
}
55+
}
56+
57+
string line;
58+
string last;
59+
map<string, SchoolClass> classes;
60+
while (true) {
61+
++lineNum;
62+
getline(ifs, line);
63+
if (!ifs) {
64+
if (ifs.eof() && line.size() == 0) break;
65+
else error("Error. Read error");
66+
}
67+
smatch matches;
68+
if (!regex_match(line, matches, row)) cerr << "bad line: " << lineNum << '\n';
69+
if (matches[1] == "Alle klasser") {
70+
last = line;
71+
break;
72+
}
73+
string classNum;
74+
string temp = matches[1];
75+
for (int i = 0; i < temp.size(); ++i) {
76+
if (isdigit(temp[i])) classNum += temp[i];
77+
else {
78+
if (i == 0) classNum = temp;
79+
break;
80+
}
81+
}
82+
int curr_boy = from_string<int>(matches[2]);
83+
int curr_girl = from_string<int>(matches[3]);
84+
int curr_total = from_string<int>(matches[4]);
85+
if (curr_boy + curr_girl != curr_total) error("bad row sum\n");
86+
SchoolClass& cl = classes[classNum];
87+
cl.boys += curr_boy;
88+
cl.girls += curr_girl;
89+
cl.total += curr_total;
90+
}
91+
92+
vector<pair<int, map<string, SchoolClass>::iterator>> classNumbers;
93+
vector<map<string, SchoolClass>::iterator> others;
94+
for (auto it = classes.begin(); it != classes.end(); ++it) {
95+
string s = it->first;
96+
string digits;
97+
for (int i = 0; i < s.size(); ++i) {
98+
if (isdigit(s[i])) digits += s[i];
99+
else break;
100+
}
101+
if (digits.size() == 0) {
102+
others.push_back(it);
103+
continue;
104+
}
105+
int num = 0;
106+
istringstream iss{ digits };
107+
iss >> num;
108+
classNumbers.push_back(pair<int, map<string, SchoolClass>::iterator>{ num, it });
109+
}
110+
sort(classNumbers.begin(), classNumbers.end(),
111+
[](pair<int, map<string, SchoolClass>::iterator> pair1,
112+
pair<int, map<string, SchoolClass>::iterator> pair2)
113+
{ return pair1.first < pair2.first; });
114+
115+
ofs << first << "\tFORSKEL" << endl;
116+
for (int i = 0; i < classNumbers.size(); ++i) {
117+
ofs << classNumbers[i].second->first
118+
<< '\t' << classNumbers[i].second->second.boys
119+
<< '\t' << classNumbers[i].second->second.girls
120+
<< '\t' << classNumbers[i].second->second.total
121+
<< '\t';
122+
if (i == 0) ofs << "-" << endl;
123+
else {
124+
int dif = classNumbers[i].second->second.total - classNumbers[i - 1].second->second.total;
125+
ofs.setf(ios_base::showpos);
126+
ofs << dif << endl;
127+
ofs.unsetf(ios_base::showpos);
128+
}
129+
}
130+
for (int i = 0; i < others.size(); ++i) {
131+
ofs << others[i]->first << '\t' << others[i]->second.boys
132+
<< '\t' << others[i]->second.girls << '\t' << others[i]->second.total
133+
<< "\t-" << endl;
134+
}
135+
ofs << last << "\t-";
136+
137+
cout << vsp_2;
138+
break;
139+
}
140+
case PRINTACTIONLIST:
141+
cout << actionList;
142+
break;
143+
case EXIT:
144+
cond = false;
145+
break;
146+
default:
147+
error("Error. Incorrect action number");
148+
break;
149+
}
150+
}
151+
catch (runtime_error& e) {
152+
cerr << e.what() << endl;
153+
}
154+
catch (...) {
155+
cerr << "Error. Exception\n";
156+
return 1;
157+
}
158+
return 0;
159+
}
160+
161+
void ClearInput(istream& is)
162+
{
163+
is.clear();
164+
is.ignore(numeric_limits<streamsize>::max(), '\n');
165+
}

‎Chapter_23/C23_Exercise_23.11.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* Exercise 23.11 */
2+
3+
using namespace std;
4+
5+
const char* sp_2 = " ";
6+
const char* sp_4 = " ";
7+
const char* sp_6 = " ";
8+
const char* sp_8 = " ";
9+
const char* vsp_2 = "\n\n";
10+
const char* vsp_3 = "\n\n\n";
11+
const char* vsp_4 = "\n\n\n\n";
12+
13+
void ClearInput(istream& is);
14+
15+
struct bad_from_string : std::bad_cast { // class for reporting string cast errors
16+
const char* what() const override
17+
{
18+
return "bad cast from string";
19+
}
20+
};
21+
22+
template<typename T> T from_string(const string& s)
23+
{
24+
istringstream is{ s };
25+
T t;
26+
if (!(is >> t)) throw bad_from_string{};
27+
return t;
28+
}
29+
30+
struct SchoolClass {
31+
int boys;
32+
int girls;
33+
int total;
34+
SchoolClass() : boys{ 0 }, girls{ 0 }, total{ 0 } {}
35+
};

‎Chapter_23/C23_Exercise_23.12.cpp

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/* Exercise 23.12 */
2+
3+
#include<iostream>
4+
#include<istream>
5+
#include<fstream>
6+
#include<sstream>
7+
#include<iomanip>
8+
#include<string>
9+
#include<vector>
10+
#include<regex>
11+
#include"C23_Exercise_23.12.h"
12+
13+
using namespace std;
14+
15+
inline void error(string s) { throw runtime_error(s); }
16+
inline void error(const string& s, const string& s2) { error(s + s2); }
17+
inline void error(const string& s, int i) { ostringstream os; os << s << ": " << i; error(os.str()); }
18+
inline void keep_window_open() { char ch; cin >> ch; }
19+
20+
int main()
21+
{
22+
enum Action {
23+
EXIT = -1, PRINTACTIONLIST,
24+
CASE1, CASE2, CASE3, CASE4, CASE5
25+
};
26+
const string actionList = "\tList of actions:\n"
27+
" (1) Reformat to ISO date\n"
28+
" (-1) Exit, (0) Print the list of actions\n";
29+
cout << actionList;
30+
int action;
31+
bool cond{ true };
32+
while (cond) try {
33+
cout << "\nPlease enter the action: ";
34+
if (!(cin >> action)) { ClearInput(cin); error("Error. Incorrect input"); }
35+
char ch;
36+
cin.get(ch);
37+
switch (action) {
38+
case CASE1: {
39+
cout << endl;
40+
cout << sp_2 << "Please enter a file name: ";
41+
string fileName;
42+
getline(cin, fileName);
43+
if (!cin) error("Error. Incorrect input");
44+
ifstream ifs{ fileName };
45+
if(!ifs) error("Error. File opening error");
46+
ofstream ofs{ "C23_Exercise_23.12_reformat.txt" };
47+
if (!ofs) error("Error. File opening error");
48+
49+
while (true) {
50+
string s;
51+
getline(ifs, s);
52+
if (!ifs) {
53+
if (ifs.eof()) break;
54+
else error("Error. Read error");
55+
}
56+
ReformatDateToISO(ofs, s);
57+
}
58+
59+
cout << vsp_2;
60+
break;
61+
}
62+
case PRINTACTIONLIST:
63+
cout << actionList;
64+
break;
65+
case EXIT:
66+
cond = false;
67+
break;
68+
default:
69+
error("Error. Incorrect action number");
70+
break;
71+
}
72+
}
73+
catch (runtime_error& e) {
74+
cerr << e.what() << endl;
75+
}
76+
catch (...) {
77+
cerr << "Error. Exception\n";
78+
return 1;
79+
}
80+
return 0;
81+
}
82+
83+
void ClearInput(istream& is)
84+
{
85+
is.clear();
86+
is.ignore(numeric_limits<streamsize>::max(), '\n');
87+
}
88+
89+
void ReformatDateToISO(ostream& os, const string& s)
90+
{
91+
constexpr int nPatterns = 4;
92+
constexpr int nDigitInYear = 4;
93+
constexpr int nDigitInMonth = 2;
94+
constexpr int nDigitInDay = 2;
95+
/* date pattern:
96+
dd/mm/yyyy OR dd-mm-yyyy OR dd.mm.yyyy OR
97+
mm/dd/yyyy OR mm-dd-yyyy OR mm.dd.yyyy OR
98+
yyyy/mm/dd OR yyyy-mm-dd OR yyyy.mm.dd OR
99+
yyyy/dd/mm OR yyyy-dd-mm OR yyyy.dd.mm
100+
*/
101+
string db{ R"((^|\s|$))" }; // date boundary
102+
string sep{ R"([./-])" }; // separator list
103+
string d{ R"((0?[1-9]|[12]\d|3[01]))" }; // day: D or DD
104+
string m{ R"((0?[1-9]|1[0-2]))" }; // month: M or MM
105+
string y{ R"((\d{4}))" }; // year: YYYY
106+
constexpr int sepGroupBegin = 1;
107+
constexpr int sepGroupEnd = 5;
108+
109+
vector<regex> pattern(nPatterns);
110+
vector<PatternGroup> pg(nPatterns);
111+
112+
pattern[0] = regex{ db + d + sep + m + sep + y + db };
113+
pg[0] = PatternGroup{ 4, 3, 2 };
114+
115+
pattern[1] = regex{ db + m + sep + d + sep + y + db };
116+
pg[1] = PatternGroup{ 4, 2, 3 };
117+
118+
pattern[2] = regex{ db + y + sep + m + sep + d + db };
119+
pg[2] = PatternGroup{ 2, 3, 4 };
120+
121+
pattern[3] = regex{ db + y + sep + d + sep + m + db };
122+
pg[3] = PatternGroup{ 2, 4, 3 };
123+
124+
string line = s;
125+
for (int i = 0; i < nPatterns; ++i) {
126+
string formatted;
127+
string::const_iterator itFirst = line.begin();
128+
string::const_iterator itLast = line.end();
129+
while (true) {
130+
smatch matched;
131+
if (!regex_search(itFirst, itLast, matched, pattern[i])) {
132+
formatted += string{ itFirst, itLast };
133+
break;
134+
}
135+
formatted += string{ itFirst, matched[0].first };
136+
formatted += string{ matched[sepGroupBegin].first, matched[sepGroupBegin].second };
137+
formatted += string{ matched[pg[i].y] };
138+
formatted += '-';
139+
if (matched[pg[i].m].second - matched[pg[i].m].first < nDigitInMonth) {
140+
formatted += '0';
141+
}
142+
formatted += string{ matched[pg[i].m] };
143+
formatted += '-';
144+
if (matched[pg[i].d].second - matched[pg[i].d].first < nDigitInDay) {
145+
formatted += '0';
146+
}
147+
formatted += string{ matched[pg[i].d] };
148+
formatted += string{ matched[sepGroupEnd].first, matched[sepGroupEnd].second };
149+
itFirst = matched.suffix().first;
150+
}
151+
line = formatted;
152+
}
153+
os << line << endl;
154+
}

‎Chapter_23/C23_Exercise_23.12.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* Exercise 23.12 */
2+
3+
using namespace std;
4+
5+
const char* sp_2 = " ";
6+
const char* sp_4 = " ";
7+
const char* sp_6 = " ";
8+
const char* sp_8 = " ";
9+
const char* vsp_2 = "\n\n";
10+
const char* vsp_3 = "\n\n\n";
11+
const char* vsp_4 = "\n\n\n\n";
12+
13+
void ClearInput(istream& is);
14+
15+
void ReformatDateToISO(ostream& os, const string& s);
16+
17+
struct bad_from_string : std::bad_cast { // class for reporting string cast errors
18+
const char* what() const override
19+
{
20+
return "bad cast from string";
21+
}
22+
};
23+
24+
template<typename T> T from_string(const string& s)
25+
{
26+
istringstream is{ s };
27+
T t;
28+
if (!(is >> t)) throw bad_from_string{};
29+
return t;
30+
}
31+
32+
struct PatternGroup {
33+
int y;
34+
int m;
35+
int d;
36+
PatternGroup() : y{ 0 }, m{ 0 }, d{ 0 } {}
37+
PatternGroup(int year, int month, int day) : y{ year }, m{ month }, d{ day } {}
38+
};

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /