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" };
	read(ist, sum);
	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 ',':
	{
		return Token(ch);
	}
	case '#':
	{
		return Token(let);
	}
	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;
		return Token(number, 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 == "quit") return Token(quitProg);
			if (s == "sqrt") return Token(sqroot);
			if (s == "pow") return Token(power);
			if (s == "const") return Token(constant);
			if (s == "reset") return Token(reset);
			if (s == "help" || s == "Help") return Token(help);
			return Token(name, s);
		}
		error("Bad token");
		return Token(' ');
	}
	}
}

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.exceptions(ist.exceptions() | ios_base::badbit);
	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);

	read_file(_input_1, ost);
	read_file(_input_2, ost);
}

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.exceptions(ist.exceptions() | ios_base::badbit);

	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);

	ost << read_file(_input_1) + read_file(_input_2);
}

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 (read_roman_string(roman_string)) {
			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 };
};

struct Reading {
	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);

	ist.exceptions(ist.exceptions() | ios_base::badbit);

	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
read 4 years of readings
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"

struct Reading {
	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;
}

vector<Reading> temps;

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

void read_file(vector<Reading>& _temps, string _file_name) {
	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
{
	read_file(temps, iname);
	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:
Reading file.
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"

struct Reading {
	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;
}

vector<Reading> temps;

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"

struct Reading {
	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;
}

vector<Reading> temps;

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

void read_file(vector<Reading>& _temps, string _file_name) {
	if (!ist) { error("Could not open file", _file_name); }
	cout << "Reading file." << endl;
	int h;
	double t;
	while (ist >> h >> t) {
		temps.push_back(Reading{ 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
{
	read_file(temps, iname);
	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:
Reading file.
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"

struct Reading {
	int hour;
	double temperature;
};

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

vector<Reading> temps;

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