# sum up all integers from input text file

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 10 Exercise 11
Using std_lib_facilities.h by Bjarne Stroustrup.

```//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 11

#include "std_lib_facilities.h"

void read(ifstream& _ist, double& _sum) {
char in;

while (true) {
if (_ist.eof()) {
break;
}
else {
_ist >> in;
if (isdigit(in)) {
_ist.unget();
double d;
_ist >> d;
_sum += d;
}
}
}
}

void calculate() {
double sum = 0;
ifstream ist{ "input/ch10_11_in.txt" };
cout << sum << endl;
}

int main()
try {

calculate();
keep_window_open();
}
catch (exception& e) {
cout << e.what() << endl;
keep_window_open();
}
catch (...) {
cout << "Exiting" << endl;
keep_window_open();
}
```
```Output:
26
Please enter a character to exit
```
```Input-File: ch10_11_in.txt
bears: 17 elephants 9 end
```

# file input calculator

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 10 Exercise 10
Using std_lib_facilities.h by Bjarne Stroustrup.

```//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 10

#include "std_lib_facilities.h"

const char let = '#';
const char quitProg = 'Q';
const char print = ';';
const char number = '8';
const char name = 'a';
const char sqroot = 'S';
const char power = 'P';
const char constant = 'C';
const char reset = 'R';
const char help = 'H';

struct Token {
char kind;
double value;
string name;
Token(char ch) :kind(ch), value(0) { }
Token(char ch, double val) :kind(ch), value(val) { }
Token(char ch, string val) :kind(ch), name(val) { }
};

class Token_stream {
bool full;
Token buffer;
;
public:
Token_stream() :full(0), buffer(0) { }
Token get(ifstream& ist);
void unget(Token t) { buffer = t; full = true; }
void ignore(char);
};

Token Token_stream::get(ifstream& ist)
{
/*
if (full) {
full = false;
return buffer;
}

char ch;
ist >> ch;
*/

if (full) {
full = false; return buffer;
}
char ch;
ist.get(ch);

while (isspace(ch)) {
if (ch == '\n') return Token(print); // if newline detected, return print Token
ist.get(ch);
}

switch (ch) {
case '(':
case ')':
case '+':
case '-':
case '*':
case '/':
case '%':
case ';':
case '=':
case 'k':
case ',':
{
}
case '#':
{
}
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
ist.unget();
double val;
ist >> val;
}
default:
{
if (isalpha(ch) || ch == '_') { //is ch a letter?
string s;
s += ch;
while (ist.get(ch) && (isalpha(ch) || isdigit(ch) || ch == '_')) { //reads chars, strings or digits
s += ch;
}
ist.unget(); //puts the most recently read character back into the stream
if (s == "help" || s == "Help") return Token(help);
}
}
}
}

void Token_stream::ignore(char c)
{
if (full && c == buffer.kind) {
full = false;
return;
}
full = false;
char ch;
while (cin >> ch) {
if (ch == c) return;
}
}

struct Variable {
string name;
double value;
bool immutable;
Variable(string n, double v, bool i) :name(n), value(v), immutable(i) { }
};

class Symbol_table {
public:
vector<Variable> var_table;
double get(string);
void set(string, double);
bool is_declared(string);
double declare(char, ifstream& ist);
bool is_immutable(string);
};

Token_stream ts;
double expression(ifstream& ist);
double primary(ifstream& ist);

double Symbol_table::get(string s)
{
for (int i = 0; i < var_table.size(); ++i) {
if (var_table[i].name == s) {
return var_table[i].value;
}
}
error("get: undefined name ", s);
return 0.0;
}

void Symbol_table::set(string s, double d)
{
for (int i = 0; i <= var_table.size(); ++i) {
if (var_table[i].name == s) {
var_table[i].value = d;
return;
}
}
error("set: undefined name ", s);
}

bool Symbol_table::is_declared(string s)
{
for (int i = 0; i < var_table.size(); ++i) {
if (var_table[i].name == s) return true;
}
return false;
}

double Symbol_table::declare(char kind, ifstream& ist)
{
Token t = ts.get(ist);
if (t.kind != name) {
error("name expected in declaration");
}

string name = t.name;
if (kind == let || kind == constant) {
if (is_declared(name)) error(name, " declared twice");
}
else if (kind == reset) {
if (!is_declared(name))
error(name, " has not been declared");
if (is_immutable(name))
error(name, " is a constant");
}
else {
error("unknown statement");
}

Token t2 = ts.get(ist);
if (t2.kind != '=') error("= missing in declaration of ", name);
double d = expression(ist);
if (is_declared(name))
set(name, d);
else
var_table.push_back(Variable(name, d, (kind == constant)));
return d;
}

bool Symbol_table::is_immutable(string s)
{
for (int i = 0; i<int(var_table.size()); ++i)
if (var_table[i].name == s && var_table[i].immutable) return true;
return false;
}

double pow_function(Token _t, ifstream& ist) {
_t = ts.get(ist);
if (_t.kind != '(') {
error("'(' expected");
}

double x = expression(ist);

_t = ts.get(ist);
if (_t.kind != ',') {
error("',' expected");
}

double n = expression(ist);
_t = ts.get(ist);
if (_t.kind == ')') {
return pow(x, n);
}
else {
error("Expected ')'");
}
}

double sqrt_function(Token _t, ifstream& ist) {
_t = ts.get(ist);
if (_t.kind != '(') {
error("'(' expected");
}
ts.unget(_t);
double d = primary(ist);
if (d < 0.0) {
error("negative square root");
}
return sqrt(d);
}

Symbol_table st;

double primary(ifstream& ist)
{
Token t = ts.get(ist);
switch (t.kind) {
case '(':
{
double d = expression(ist);
t = ts.get(ist);
if (t.kind != ')') error("')' expected");
return d;
}
case '-':
{
return -primary(ist);
}
case '+':
{
return primary(ist);
}
case number:
{
return t.value;
}
case sqroot:
{
return sqrt_function(t, ist);
}
case power:
{
return pow_function(t, ist);
}
case name:
{
return st.get(t.name);
}
default:
{
error("primary expected");
return 0.0;
}
}
}

double term(ifstream& ist)
{
double left = primary(ist);
while (true) {
Token t = ts.get(ist);
switch (t.kind) {
case 'k':
{
left *= 1000;
break;
}
case '*':
{
left *= primary(ist);
break;
}
case '/':
{
double d = primary(ist);
if (d == 0) error("divide by zero");
left /= d;
break;
}
case '%':
{
int i1 = narrow_cast<int>(left);
int i2 = narrow_cast<int>(primary(ist));
if (i2 == 0) error("%: divide by zero");
left = i1%i2;
break;
}

default: {
ts.unget(t);
return left;
}
}
}
}

double expression(ifstream& ist)
{
double left = term(ist);
while (true) {
Token t = ts.get(ist);
switch (t.kind) {
case '+':
{
left += term(ist);
break;
}
case '-':
{
left -= term(ist);
break;
}
default:
{
ts.unget(t);
return left;
}
}
}
}

double statement(ifstream& ist)
{
Token t = ts.get(ist);
double d;
if (t.kind == let || t.kind == reset || t.kind == constant) {
d = st.declare(t.kind, ist);
}
else {
ts.unget(t);
d = expression(ist);
}
t = ts.get(ist);
if (t.kind != print) {
error("Missing terminator");
}

return d;
}

void clean_up_mess()
{
ts.ignore(print);
}

const string prompt = "> ";
const string result = "= ";

void calculate(ifstream& ist, ofstream& ost)
{
ost << "Welcome to my calculator.\n"
<< "Just hit enter or ; at the end of your function to calculate.\n"
<< "Enter help or Help for help or quit to exit the program.\n";
while (ist) try {
ost << prompt;
Token t = ts.get(ist);
while (t.kind == print) {
t = ts.get(ist);
}
if (t.kind == help) {
ost << "You can use / *-+operators.\n"
<< "Declaring variables using #, for example: # x = 5.\n";
}
else {
if (t.kind == quitProg) {
return;
}
ts.unget(t);
ost << result << statement(ist) << endl;
break;
}
}
catch (runtime_error& e) {
ost << e.what() << endl;
clean_up_mess();
}
}

int main()

try {

string iname = "input/ch10_p378_10_input.txt";
string oname = "output/ch10_p378_10_output.txt";
ifstream ist{ iname };
ofstream ost{ oname };

calculate(ist, ost);
keep_window_open();
//return 0;
}
catch (exception& e) {
cerr << "exception: " << e.what() << endl;
char c;
while (cin >> c&& c != ';');
return 1;
}
catch (...) {
cerr << "exception\n";
char c;
while (cin >> c && c != ';');
return 2;
}
```
```Output:
Please enter a character to exit
```
```Input-File: ch10_p378_10_input.txt
6+5;
```
```Output-File: ch10_p378_10_output.txt
Welcome to my calculator.
Just hit enter or ; at the end of your function to calculate.
Enter help or Help for help or quit to exit the program.
> = 11
```

# concatenating files containing whitespace-separated words

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 10 Exercise 9
Using std_lib_facilities.h by Bjarne Stroustrup.

```//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 9

#include "std_lib_facilities.h"

void read_file(string& _input, ofstream& _ost) {
ifstream ist{ _input };
string result;
if (!ist) error("can't open input file ", _input);
ist >> result;

while (true) {
_ost << result << endl;
if (ist.eof()) {
break;
}
else {
ist >> result;
}
}
}

void write_file(string& _output, string& _input_1, string& _input_2) {
ofstream ost{ _output };
if (!ost) error("can't open output file", _output);

}

void calculate() {
string input_1 = "input/ch10_9_input_1.txt";
string input_2 = "input/ch10_9_input_2.txt";
string output = "output/ch10_9_output_1+2.txt";

cout << "Combining files " << input_1 << " & " << input_2 << "...";
write_file(output, input_1, input_2);
cout << " Done!" << endl;
cout << output << " successfully written." << endl;
}

int main()
try
{
calculate();

keep_window_open();
}
catch (runtime_error e) {
cout << e.what() << endl;
keep_window_open();
}
catch (...) {
cout << "Exiting" << endl;
keep_window_open();
}
```
```Output:
Combining files input/ch10_9_input_1.txt & input/ch10_9_input_2.txt... Done!
output/ch10_9_output_1+2.txt successfully written.
Please enter a character to exit
```
```Input-File 1: ch10_9_input_1.txt
this is a test
```
```Input-File 2: ch10_9_input_2.txt
and so is this
```
```Output-File: ch10_9_output_1+2.txt
this
is
a
test
and
so
is
this
```

# concatenating files

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 10 Exercise 8
Using std_lib_facilities.h by Bjarne Stroustrup.

```//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 8

#include "std_lib_facilities.h"

string read_file(string& _input) {
ifstream ist{ _input };
string result;
if (!ist) error("can't open input file ", _input);

ist >> result;
return result;
}

void write_file(string& _output, string& _input_1, string& _input_2) {
ofstream ost{ _output };
if (!ost) error("can't open output file", _output);

}

void calculate() {
string input_1 = "ch10_8_input_1.txt";
string input_2 = "ch10_8_input_2.txt";
string output = "ch10_8_output_1+2.txt";

cout << "Combining files " << input_1 << " & " << input_2 << "...";
write_file(output, input_1, input_2);
cout << " Done!" << endl;
cout << output << " successfully written." << endl;
}

int main()
try
{
calculate();

keep_window_open();
}
catch (runtime_error e) {
cout << e.what() << endl;
keep_window_open();
}
catch (...) {
cout << "Exiting" << endl;
keep_window_open();
}
```
```Output:
Combining files ch10_8_input_1.txt & ch10_8_input_2.txt...can't open input file ch10_8_input_2.txt
Please enter a character to exit
```
```Input-File 1: ch10_8_input_1.txt
000
```
```Input-File 2: ch10_8_input_2.txt
111
```
```Output-File: ch10_8_output_1+2.txt
000
111
```

# roman integer class 1.0

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 10 Exercise 6
Using std_lib_facilities.h by Bjarne Stroustrup.

My project includes the following files:
p377_6_romanIntMain.cpp my main cpp file
p377_6_romanIntClass.h my roman integer class header file

p377_6_romanIntMain.cpp my main cpp file

```//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 6

#include "p377_6_romanIntClass.h"

int main()
try
{
Roman_int r;
r.set_values();
//cout << r;

keep_window_open();
}
catch (runtime_error e) {
cout << e.what() << endl;
keep_window_open();
}
catch (...) {
cout << "Exiting" << endl;
keep_window_open();
}
```

p377_6_romanIntClass.h my roman integer class header file

```#pragma once
//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 6

#include "std_lib_facilities.h"

vector<char> roman_chars = {
'N', 'I', 'V', 'X', 'L', 'C', 'D', 'M'
};

int roman_char_value(char ch) {
switch (ch) {
case 'N':
return 0;
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
default:
return -1;
}
}

class Roman_int {
private:
string roman_string;
int roman_int;
public:

Roman_int() {};
Roman_int(string& _roman_string);

void set_values();
string get_string() { return roman_string; }
int get_int() { return roman_int; }
};

ostream& operator<<(ostream& os, Roman_int _roman_int) {
os << "Roman_int conversion:\n"
<< _roman_int.get_string()
<< " equals " << _roman_int.get_int() << endl;
return os;
}

Roman_int::Roman_int(string& _roman_string) {
roman_string = _roman_string;
}

bool read_roman_string(string& _value) {
string _value_temp;
if (cin >> _value_temp) {
_value = _value_temp;
return true;
}
else {
return false;
}
}

bool check_char_validity(string& _value) {
if (_value.size() == 1) {
cout << "Checking validity of roman char... ";
}
else {
cout << "Checking validity of roman chars... ";
}

int size = int(_value.size());
vector<int> invalid_index;

for (int i = 0; i < size; i++) {
int check = 0;
for (int j = 0; j < roman_chars.size(); j++) {
if (roman_chars[j] == _value[i]) {
check++;
}
}
if (check == 0) {
invalid_index.push_back(i);
}
}

if (invalid_index.size() != 0) {
cout << "Invalid char: ";
for (int i = 0; i < invalid_index.size(); i++) {
cout << _value[invalid_index[i]] << " ";
}
cout << endl;
return false;
}
else {
if (_value.size() == 1) {
cout << "Valid roman char." << endl;
return true;
}
else {
cout << "Valid roman chars." << endl;
return true;
}
}
}

bool check_char_count(string& _value) {
cout << "Checking number of roman chars... ";

int size = _value.size();
vector<int> counter(roman_chars.size(), 0);

for (int i = 0; i < size; i++) {
for (int j = 0; j < roman_chars.size(); j++) {
if (_value[i] == roman_chars[j]) {
counter[j]++;
}
}
}

int check = 0;
for (int i = 0; i < roman_chars.size(); i++) {
if (counter[i] > 1 && (roman_chars[i] == 'V' || roman_chars[i] == 'L' || roman_chars[i] == 'D')) {
cout << "Invalid number of " << roman_chars[i] << "." << endl;
check++;
}
else if (counter[i] > 3 && (roman_chars[i] == 'I' || roman_chars[i] == 'X' || roman_chars[i] == 'C' || roman_chars[i] == 'M')) {
cout << "Invalid number of " << roman_chars[i] << "." << endl;
check++;
}
}
if (check == 0) {
if (_value.size() == 1) {
cout << "It is a single char." << endl;
}
else {
cout << "Valid number of chars." << endl;
}
return true;
}
else {
return false;
}
}

void deconpose_roman_string(string& _value, int& _digit) {
cout << "Decomposing roman string... ";

int resulting_val = 0;
int size = _value.size();
int check = 0;

//fill vector
vector<int> value_ints;
for (int i = 0; i < size; i++) {
value_ints.push_back(roman_char_value(_value[i]));
}

/*
I placed before V or X indicates one less, so four is IV (one less than five) and nine is IX (one less than ten)
X placed before L or C indicates ten less, so forty is XL (ten less than fifty) and ninety is XC (ten less than a hundred)
C placed before D or M indicates a hundred less, so four hundred is CD (a hundred less than five hundred) and nine hundred is CM (a hundred less than a thousand)
*/

if (size == 1) {
resulting_val = value_ints[0];
}
else {
for (int i = 0; i < size; i++) {
if (_value[i] == 'I' && (_value[i + 1] == 'V' || _value[i + 1] == 'X')) {
if (i == 0 && size == 2) {
resulting_val += (value_ints[i + 1] - value_ints[i]);
i++;
}
else if ((value_ints[i + 1] - value_ints[i]) < resulting_val){
resulting_val += (value_ints[i + 1] - value_ints[i]);
i++;
}
else {
cout << "Number not existing." << endl;
check = 1;
}
}
else if (_value[i] == 'X' && (_value[i + 1] == 'L' || _value[i + 1] == 'C')) {
if (i == 0 && size == 2) {
resulting_val += (value_ints[i + 1] - value_ints[i]);
i++;
}
else if ((value_ints[i + 1] - value_ints[i]) < resulting_val) {
resulting_val += (value_ints[i + 1] - value_ints[i]);
i++;
}
else {
cout << "Number not existing." << endl;
check = 1;
}
}
else if (_value[i] == 'C' && (_value[i + 1] == 'D' || _value[i + 1] == 'M')) {
if (i == 0 && size == 2) {
resulting_val += (value_ints[i + 1] - value_ints[i]);
i++;
}
else if ((value_ints[i + 1] - value_ints[i]) < resulting_val) {
resulting_val += (value_ints[i + 1] - value_ints[i]);
i++;
}
else {
cout << "Number not existing." << endl;
check = 1;
}
}
else {
resulting_val += value_ints[i];
}
}
}

if (check == 0) {
cout << "resulting value = " << resulting_val << endl;
_digit = resulting_val;
}
}

void Roman_int::set_values() {
//while (true) {
cout << "Enter roman string or char:" << endl;
//read roman string from user
if (roman_string == "p") {
//break;
}
//check if valid roman chars
//check if valid count of chars
else if (check_char_validity(roman_string) && check_char_count(roman_string)) {
//decompose roman string
deconpose_roman_string(roman_string, roman_int);
cout << "Roman_int conversion:\n"
<< get_string()
<< " equals " << get_int() << endl;
}
}
//}
}
```
```Output:
Enter roman string or char:
IV
Checking validity of roman chars... Valid roman chars.
Checking number of roman chars... Valid number of chars.
Decomposing roman string... resulting value = 4
Roman_int conversion:
IV equals 4
Please enter a character to exit
```

# reading a structured file

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 10 Exercise 5
Using std_lib_facilities.h by Bjarne Stroustrup.

```//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 5

#include "std_lib_facilities.h"

const int not_a_reading = -7777;
const int not_a_month = -1;

struct Day {
vector<double> hour{ vector<double>(24,not_a_reading) };
};

struct Month {
int month{ not_a_month };
vector<Day> day{ 32 };
};

struct Year {
int year;
vector<Month> month{ 12 };
};

int day;
int hour;
double temperature;
};

istream& operator>>(istream& is, Reading& r) {
char ch1;
if (is >> ch1 && ch1 != '(') {
is.unget();
is.clear(ios_base::failbit);
return is;
}

char ch2;
int d;
int h;
double t;
is >> d >> h >> t >> ch2;
if (!is || ch2 != ')') error("bad reading");
r.day = d;
r.hour = h;
r.temperature = t;
return is;
}

void end_of_loop(istream& ist, char term, const string& message) {
if (ist.fail()) {
ist.clear();
char ch;
if (ist >> ch && ch == term) return;
error(message);
}
}

constexpr int implausible_min = -200;
constexpr int implausible_max = 200;

bool is_valid(const Reading& r) {
if (r.day < 1 || 31 < r.day) return false;
if (r.hour < 0 || 23 < r.hour) return false;
if (r.temperature < implausible_min || implausible_max < r.temperature) {
return false;
}
return true;
}

vector<string> month_input_tbl = {
"jan", "feb", "mar", "apr", "may", "jun", "jul",
"aug", "sep", "oct", "nov", "dec"
};

int month_to_int(string s) {
for (int i = 0; i < 12; ++i) {
if (month_input_tbl[i] == s) return i;
}
}

vector<string> month_print_tbl = {
"January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"
};

string int_to_month(int i) {
if (i < 0 || 12 <= i) error("bad month index");
return month_print_tbl[i];
}

istream& operator>>(istream& is, Month& m) {
char ch = 0;
if (is >> ch && ch != '{') {
is.unget();
is.clear(ios_base::failbit);
return is;
}

string month_marker;
string mm;
is >> month_marker >> mm;
if (!is || month_marker != "month") error("bad start of month");
m.month = month_to_int(mm);

int duplicates = 0;
int invalids = 0;
for (Reading r; is >> r;) {
if (is_valid(r)) {
if (m.day[r.day].hour[r.hour] != not_a_reading) {
++duplicates;
}
m.day[r.day].hour[r.hour] = r.temperature;
}
else {
++invalids;
}
}
if (invalids) error("invalid readings in month", invalids);
if (duplicates) error("duplicate readings in month", duplicates);
end_of_loop(is, '}', "bad end of month");
return is;
}

istream& operator>>(istream& is, Year& y) {
char ch;
is >> ch;
if (ch != '{') {
is.unget();
is.clear(ios::failbit);
return is;
}

string year_marker;
int yy;
is >> year_marker >> yy;
if (!is || year_marker != "year") error("bad start of year");
y.year = yy;

while (true) {
Month m;
if (!(is >> m)) break;
y.month[m.month] = m;
}

end_of_loop(is, '}', "bad end of year");
return is;
}

ostream& operator<<(ostream& os, Year& y) {
os << y.year;
return os;
}

void print_years(ostream& ost, Year& y) {
ost << y << endl;
}

int main()
try
{
cout << "Please enter input file name\n";
string iname;
cin >> iname;

ifstream ist{ iname };
if (!ist) error("can't open input file ", iname);

cout << "Please enter output file name\n";
string oname;
cin >> oname;
ofstream ost{ oname };
if (!ost) error("can't open output file", oname);

vector<Year> ys;
while (true) {
Year y;
if (!(ist >> y)) break;
ys.push_back(y);
}

cout << "read " << ys.size() << " years of readings\n";

for (Year& y : ys) print_years(ost, y);

keep_window_open();

}
catch (runtime_error e) {
cout << e.what() << endl;
keep_window_open();
}
catch (...) {
cout << "Exiting" << endl;
keep_window_open();
}
```
```Output:
Please enter input file name
input/input.txt
Please enter output file name
output/output.txt
Please enter a character to exit
```
```Input-File input.txt:
{ year 1990 }

{ year 1991
{ month jun }
}

{ year 1992
{ month jan
(1 0 61.5)
}
{ month feb
(1 1 64)
(2 2 65.2)
}
}

{year 2000
{ month feb
(1 1 68)
(2 3 66.66 )
(1 0 67.2)
}
{ month dec
(15 15 -9.2)
(15 14 -8.8)
(14 0 -2)
}

}
```
```Output-File output.txt:
1990
1991
1992
2000
```

# read random hour + temperature pairs [fahrenheite + celsius indicator] and calculate mean and median values

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 10 Exercise 4.1
Using std_lib_facilities.h by Bjarne Stroustrup.

```//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 4.1

#include "std_lib_facilities.h"

int hour;
double temperature;
char suffix;
Reading(int h, double t, char s) :hour(h), temperature(t), suffix(s) {}
};

ostream& operator<<(ostream& os, Reading& _temps) {
os << _temps.hour << " " << _temps.temperature << " " << _temps.suffix << endl;
return os;
}

struct Stats {
double mean;
double median;
};

ostream& operator<<(ostream& os, Stats _stats) {
os << "mean: " << _stats.mean << " median: " << _stats.median << endl;
return os;
}

string iname = "raw_temps.txt";
ifstream ist(iname);

if (!ist) { error("Could not open file", _file_name); }
cout << "Reading file." << endl;
int h;
double t;
char s;
while (ist >> h >> t >> s) {
if (s == 'c') {
t = (t * (9.0 / 5.0)) + 32;
s = 'f';
}
temps.push_back(Reading{ h, t, s });
}
cout << "Done!" << endl;
}

Stats calculate_stats(vector<Reading>& _temps) {
cout << "Calculating mean and median." << endl;
double sum = 0;
double mean;
double median;
int size = int(_temps.size());

for (int i = 0; i < size; i++) {
sum += _temps[i].temperature;
}
mean = sum / size;

vector<double> sorted_temps;
for (int i = 0; i < size; i++) {
sorted_temps.push_back(_temps[i].temperature);
}
sort(sorted_temps);

if (size % 2 == 0) {
median = (sorted_temps[size / 2] + sorted_temps[(size / 2) - 1]) / 2;
}
else {
median = sorted_temps[(size - 1) / 2];
}
return Stats{ mean, median };
}

int main()
try
{
cout << calculate_stats(temps);

for (Reading i : temps) {
cout << i;
}

keep_window_open();

}
catch (runtime_error e) {
cout << e.what() << endl;
keep_window_open();
}
catch (...) {
cout << "Exiting" << endl;
keep_window_open();
}
```
```Output:
Done!
Calculating mean and median.
mean: 78.444 median: 63.9
Please enter a character to exit
```
```Input-File raw_temps.txt:
0 78 c
1 1 c
2 72 c
3 65 c
4 49 f
5 48 c
6 67 f
7 20 c
8 76 f
9 36 c
10 15 c
11 16 c
12 34 c
13 37 f
14 79 f
15 60 f
16 15 c
17 1 c
18 84 c
19 79 f
20 0 c
21 86 f
22 76 c
23 73 c
0 74 f
1 22 f
2 28 f
3 30 c
4 36 c
5 0 c
6 60 f
7 78 f
8 56 c
9 51 f
10 40 f
11 52 f
12 15 f
13 47 f
14 59 f
15 82 f
16 77 c
17 46 f
18 1 c
19 0 c
20 1 c
21 2 c
22 15 c
23 36 c
0 87 c
1 29 c
```

# write random hour + temperature pairs [fahrenheite + celsius indicator]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 10 Exercise 4.0
Using std_lib_facilities.h by Bjarne Stroustrup.

```//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 4.0

#include "std_lib_facilities.h"

int hour;
double temperature;
char suffix;
Reading(int h, double t, char s) :hour(h), temperature(t), suffix(s) {}
};

ostream& operator<<(ostream& os, Reading& _temps) {
os << _temps.hour << " " << _temps.temperature << " " << _temps.suffix << endl;
return os;
}

string oname = "raw_temps.txt";
ofstream ost(oname);

int random_temperatur(int seed, int max) {
srand(seed);
return randint(max);
}

char random_suffix(int seed) {
srand(seed);
if (randint(100) <= 50) {
return 'c';
}
else {
return 'f';
}
}

void fill_vector(vector<Reading>& _temps) {
cout << "Generating Data." << endl;
int h;
double t;
char s;
int temp_hour = 0;

for (int i = 0; i < 50; i++) {
if (!(i % 24)) {
temp_hour = 0;
}

h = temp_hour;
t = random_temperatur(0, 90);
s = random_suffix(1);

_temps.push_back(Reading{ h, t, s});
temp_hour++;
}
}

void write_file(vector<Reading>& _temps) {
cout << "Writing File." << endl;
for (int i = 0; i < temps.size(); i++) {
ost << _temps[i];
}
cout << "Done!" << endl;
}

int main()
try
{

fill_vector(temps);
write_file(temps);

keep_window_open();
}
catch (runtime_error e) {
cout << e.what() << endl;
keep_window_open();
}
catch (...) {
cout << "Exiting" << endl;
keep_window_open();
}
```
```Output:
Generating Data.
Writing File.
Done!
Please enter a character to exit
```
```Output-File raw_temps.txt:
0 78 c
1 1 c
2 72 c
3 65 c
4 49 f
5 48 c
6 67 f
7 20 c
8 76 f
9 36 c
10 15 c
11 16 c
12 34 c
13 37 f
14 79 f
15 60 f
16 15 c
17 1 c
18 84 c
19 79 f
20 0 c
21 86 f
22 76 c
23 73 c
0 74 f
1 22 f
2 28 f
3 30 c
4 36 c
5 0 c
6 60 f
7 78 f
8 56 c
9 51 f
10 40 f
11 52 f
12 15 f
13 47 f
14 59 f
15 82 f
16 77 c
17 46 f
18 1 c
19 0 c
20 1 c
21 2 c
22 15 c
23 36 c
0 87 c
1 29 c
```

# read hour + temperature pairs and calculate mean and median temperature

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 10 Exercise 3
Using std_lib_facilities.h by Bjarne Stroustrup.

```//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 3

#include "std_lib_facilities.h"

int hour;
double temperature;
};

struct Stats {
double mean;
double median;
};

ostream& operator<<(ostream& os, Stats _stats) {
os << "mean: " << _stats.mean << " median: " << _stats.median << endl;
return os;
}

string iname = "output/raw_temps.txt";
ifstream ist(iname);

if (!ist) { error("Could not open file", _file_name); }
cout << "Reading file." << endl;
int h;
double t;
while (ist >> h >> t) {
}
cout << "Done!" << endl;
}

Stats calculate_stats(vector<Reading>& _temps) {
cout << "Calculating mean and median." << endl;
double sum = 0;
double mean;
double median;
int size = int(_temps.size());

for (int i = 0; i < size; i++) {
sum += _temps[i].temperature;
}
mean = sum / size;

vector<double> sorted_temps;
for (int i = 0; i < size; i++) {
sorted_temps.push_back(_temps[i].temperature);
}
sort(sorted_temps);

if (size % 2 == 0) {
median = (sorted_temps[size / 2] + sorted_temps[(size / 2) - 1]) / 2;
}
else {
median = sorted_temps[(size - 1) / 2];
}
return Stats{ mean, median };
}

int main()
try
{
cout << calculate_stats(temps);

keep_window_open();

}
catch (runtime_error e) {
cout << e.what() << endl;
keep_window_open();
}
catch (...) {
cout << "Exiting" << endl;
keep_window_open();
}
```
```Output:
Done!
Calculating mean and median.
mean: 47.64 median: 48.5
Please enter a character to exit
```
```Input-File raw_temps.txt:
0 78
1 14
2 1
3 15
4 72
5 20
6 65
7 54
8 49
9 67
10 48
11 73
12 67
13 49
14 20
15 42
16 76
17 38
18 36
19 40
20 15
21 87
22 16
23 51
0 34
1 63
2 37
3 48
4 79
5 41
6 60
7 21
8 15
9 51
10 1
11 41
12 84
13 13
14 79
15 38
16 0
17 16
18 86
19 88
20 76
21 50
22 73
23 77
0 74
1 44
```

# write random hour + temperature pairs

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 10 Exercise 2
Using std_lib_facilities.h by Bjarne Stroustrup.

```//	Philipp Siedler
//	Bjarne Stroustrup's PPP
//	Chapter 10 Exercise 2

#include "std_lib_facilities.h"

int hour;
double temperature;
};

ostream& operator<<(ostream& os, Reading& _temps) {
os << _temps.hour << " " << _temps.temperature << endl;
return os;
}

string oname = "output/raw_temps.txt";
ofstream ost(oname);

void fill_vector(vector<Reading>& _temps) {
cout << "Generating Data." << endl;
int h;
double t;
int temp_hour = 0;
for (int i = 0; i < 50; i++) {
if (!(i % 24)) {
temp_hour = 0;
}
h = temp_hour;
t = randint(90);
_temps.push_back(Reading{ h, t });
temp_hour++;
}
}

void write_file(vector<Reading>& _temps) {
cout << "Writing File." << endl;
for (int i = 0; i < temps.size(); i++) {
ost << _temps[i];
}
cout << "Done!" << endl;
}

int main()
try
{

fill_vector(temps);
write_file(temps);

keep_window_open();
}
catch(runtime_error e) {
cout << e.what() << endl;
keep_window_open();
}
catch (...) {
cout << "Exiting" << endl;
keep_window_open();
}
```
```Output:
Generating Data.
Writing File.
Done!
Please enter a character to exit
```
```Output-File raw_temps.txt:
0 78
1 14
2 1
3 15
4 72
5 20
6 65
7 54
8 49
9 67
10 48
11 73
12 67
13 49
14 20
15 42
16 76
17 38
18 36
19 40
20 15
21 87
22 16
23 51
0 34
1 63
2 37
3 48
4 79
5 41
6 60
7 21
8 15
9 51
10 1
11 41
12 84
13 13
14 79
15 38
16 0
17 16
18 86
19 88
20 76
21 50
22 73
23 77
0 74
1 44
```