permutations and combinations

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

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 6 Exercise 10

/*
input:
12
3
c
*/

#include "std_lib_facilities.h"

int factorial(int _n) {
	int fact = 1;
	while (1 < _n){
		fact *= _n;
		--_n;
		if (fact < 1) {
			error("factorial overflow");
		}
	}
	return fact;
}

int permutations(int _a, int _b) {
	if (_a < _b || _a < 1 || _b < 1) {
		error("bad permutation sizes");
	}
	return factorial(_a) / factorial(_a - _b);
}

int combinations(int _a, int _b)
{
	return permutations(_a, _b) / factorial(_b);
}

int main()
try
{
	int a;
	int b;
	string aCheck;
	string bCheck;
	char answer;
	bool permCheck = false;
	bool combCheck = false;

	cout << "Enter two integer values for permutation and combination: \n";
	cout << "Enter value for a\n";

	if (cin >> a) {}
	else{
		cin.clear();
		cin >> aCheck;
		error("Wrong value for a: ", aCheck);
	}

	cout << "Enter value for b\n";
	if (cin >> b) {}
	else {
		cin.clear();
		cin >> aCheck;
		error("Wrong value for b: ", aCheck);
	}
	if (b > a) {
		error("Value b must be smaller than a, b: ", b);
	}

	cout << "a = " << a << "\n";
	cout << "b = " << b << "\n";

	cout << "Enter 'p' for permutations, 'c' for combinations or 'b' for both:\n";
	cin >> answer;
	if (answer == 'p') {
		permCheck = true;
	}
	else if (answer == 'c') {
		combCheck = true;
	}
	else if (answer == 'b') {
		permCheck = true;
		combCheck = true;
	}
	else {
		error("Bad input", answer);
	}

	if (permCheck) {
		cout << "Permutation: " << permutations(a, b) << "\n";
	}
	if(combCheck){
		cout << "Combination: " << combinations(a, b) << "\n";
	}

	keep_window_open(".");
}

catch (runtime_error e) {
	cout << e.what() << "\n";
	keep_window_open(".");
}
catch (...) {
	cout << "Extiting" << "\n";
	keep_window_open(".");
}

Output:

Enter two integer values for permutation and combination:
Enter value for a
12
Enter value for b
3
a = 12
b = 3
Enter 'p' for permutations, 'c' for combinations or 'b' for both:
c
Combination: 220
Please enter . to exit

compose digits to integers

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

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 6 Exercise 9

//input: 1234x

#include "std_lib_facilities.h"

class Token {
public:
	char intChar;
	Token(char iCh)
		:intChar(iCh) { }
};

class Token_stream {
public:
	Token_stream();
	Token get();
	void putback(Token t);
private:
	bool full;
	Token buffer;
};

Token_stream::Token_stream()
	:full(false), buffer(0)
{
}

void Token_stream::putback(Token t)
{
	if (full) error("putback() into a full buffer");
	buffer = t;
	full = true;
}

Token Token_stream::get()
{
	if (full) {
		full = false;
		return buffer;
	}

	char iCh;
	cin >> iCh;

	switch (iCh) {
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	case 'x':
	{
		//cin.putback(iCh);
		return Token(iCh);
	}
	default:
		error("Bad token");
	}
}

Token_stream ts;

int main()
try
{
	cout << "Enter 1-4 integer values\n";
	vector<int> intFromChar;
	int intAdded = 0;
	bool check = true;
	
	while (check) {
		if (intFromChar.size() < 4) {
			Token t = ts.get();
			if (t.intChar == 'x') break; // 'x' for quit
			intFromChar.push_back(t.intChar - '0');
		}
		else{
			check = false;
		}
	}
	
	cout << "Num size: " << intFromChar.size() << "\n";

	for (int i = 0; i < intFromChar.size(); i++) {
		int result = pow(10, intFromChar.size() - i) / 10;
		intFromChar[i] = intFromChar[i] * result;
	}

	for (int i = 0; i < intFromChar.size(); i++) {
		intAdded += intFromChar[i];
	}

	if (intFromChar.size() == 1) {
		cout << intAdded << " is "
		<< intFromChar[0] << " ones\n";
	}

	if (intFromChar.size() == 2) {
		cout << intAdded << " is "
		<< intFromChar[0] << " tens and "
		<< intFromChar[1] << " ones\n";
	}

	if (intFromChar.size() == 3) {
		cout << intAdded << " is "
		<< intFromChar[0] << " hundreds and "
		<< intFromChar[1] << " tens and "
		<< intFromChar[2] << " ones\n";
	}

	if (intFromChar.size() == 4) {
		cout << intAdded << " is "
		<< intFromChar[0] << " thousands and "
		<< intFromChar[1] << " hundreds and "
		<< intFromChar[2] << " tens and "
		<< intFromChar[3] << " ones\n";
	}
	
	keep_window_open(".");
}

catch (runtime_error e) {
	cout << e.what() << "\n";
	keep_window_open(".");
}
catch (...) {
	cout << "Extiting" << "\n";
	keep_window_open(".");
}
Output:
Enter 1-4 integer values
1234x
Num size: 4
1234 is 1000 thousands and 200 hundreds and 30 tens and 4 ones
Please enter . to exit

bulls and cows [guess 4 characters]

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

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 6 Exercise 8

#include "std_lib_facilities.h"

vector<char> randomCharGen(int _seed, int _num) {
	vector <char> chosen;
	int counter = 0;
	vector <char> alphabet = { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
	'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
	't', 'u', 'v', 'w', 'x', 'y', 'z' };

	srand(_seed);
	while (chosen.size() < _num) {
		char temp = alphabet[rand() % alphabet.size()];
		if (chosen.size() == 0) {
			chosen.push_back(temp);
		}
		else{
			for (int j = 0; j < chosen.size(); j++) {
				if (temp == chosen[j]) {
					counter++;
				}
			}
			if (counter == 0) {
				chosen.push_back(temp);
			}
			else {
				counter = 0;
			}
		}
	}
	return chosen;
}

int main()
try
{
	vector <char> randomChars;
	vector <char> charGuess;
	char charGuessTemp;
	int charGuessCheck;

	int bulls = 0;
	int cows = 0;

	int charNums = 4;
	int seed;
	string seedCheck;

	string answer = "noAnswer";

	while (randomChars.size() < charNums) {
		cout << "Enter seed value between 0 and 100\n";
		if (cin >> seed && seed <= 100 && seed >= 0) {}
		else {
			cin.clear();
			cin >> seedCheck;
			error("Seed value is wrong: ", seedCheck);
		}
		randomChars = randomCharGen(seed, charNums);

		for (int i = 0; i < randomChars.size(); i++) {
			cout << randomChars[i] << "\n";
		}

		while (bulls != charNums) {
			bulls = 0;
			cows = 0;

			cout << "Enter 4 different letters\n";
			if (cin) {
				while (charGuess.size() < charNums) {
					if (cin >> charGuessTemp) {
						charGuess.push_back(charGuessTemp);
					}
					else {
						cin.clear();
						cin >> charGuessCheck;
						error("Entered wrong guess", charGuessCheck);
					}
				}
			}

			//COMPARING GUESS AND RANDOM LETTERS
			for (int i = 0; i < charNums; i++) {
				for (int j = 0; j < charNums; j++) {
					if (charGuess[i] == randomChars[j] && i == j) {
						bulls++;
					}
					else if (charGuess[i] == randomChars[j] && i != j) {
						cows++;
					}
				}
			}
			cout << "Bulls: " << bulls << " Cows: " << cows << "\n";
			charGuess.clear();
		}

		cout << "You win!\n";
		cout << "Play again? Type y for yes and n for no: ";
		cin >> answer;

		if (answer == "noAnswer") {
			error("Wrong Answer.");
		}
		else if (answer == "y") {
			randomChars.clear();
			bulls = 0;
		}
	}
	keep_window_open(".");
}

catch (runtime_error e) {
	cout << e.what() << "\n";
	keep_window_open(".");
}
catch (...) {
	cout << "Extiting" << "\n";
	keep_window_open(".");
}
Output:
Enter sentece to be checked or x to exit:
birds fly and fish swim.
OK!
x for exit or continue:
C++ rules.
OK!
x for exit or continue:
x
Please enter . to exit

grammar for bitwise logical expressions

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

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 6 Exercise 7

#include "std_lib_facilities.h"

/*
Binary And:
	Exclusive Or
	And "&" Or

Binary Exclusive Or:
	Or
	Exclusive Or "^" Or

Binary Or:
	Unary
	Or "|" Unary

Prefix Unary:
	Primary
	Unary "!" Primary
	Unary "~" Primary	

Primary:
	Number
	"("Expression")"

Number:
	integer
*/

sentence check

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

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 6 Exercise 6

/*
input:
birds fly and fish swim.
C++ rules.
x
*/

#include "std_lib_facilities.h"

//word vector setup
vector<string> nouns;
vector<string> verbs;
vector<string> conjunctions;

//initialize word vectors
void init(){
	nouns.push_back("birds");
	nouns.push_back("fish");
	nouns.push_back("C++");

	verbs.push_back("rules");
	verbs.push_back("fly");
	verbs.push_back("swim");

	conjunctions.push_back("and");
	conjunctions.push_back("or");
	conjunctions.push_back("but");
}

bool isNounString(string w) {
	for (int i = 0; i < nouns.size(); i++) {
		if (w == nouns[i]) {
			return true;
		}
	}
	return false;
}

bool isVerbString(string w) {
	for (int i = 0; i < verbs.size(); i++) {
		if (w == verbs[i]) {
			return true;
		}
	}
	return false;
}

bool isConjunctionString(string w) {
	for (int i = 0; i < conjunctions.size(); i++) {
		if (w == conjunctions[i]) {
			return true;
		}
	}
	return false;
}

bool sentences() {
	string w;
	cin >> w;
	if (!isNounString(w)) {
		return false;
	}

	string w1;
	cin >> w1;
	if (!isVerbString(w1)) {
		if (w1[w1.size() - 1] == '.') {
			return true;
		}
		else {
			return false;
		}
	}

	string w2;
	cin >> w2;
	if (!isConjunctionString(w2)) {
		return false;
	}
	return sentences();
}

int main()
try
{
	init();
	cout << "Enter sentece to be checked or x to exit:\n";

	while (true) {
		char exit;
		if (cin >> exit && exit == 'x') {
			break;
		}
		else {
			cin.putback(exit);
			bool check = sentences();
			if (check) {
				cout << "OK!\n";
				cout << "x for exit or continue:" << endl;
			}
			else {
				cout << "Not OK!\n";
				cout << "Try again:\n";
			}
		}

	}


	/*
	while (cin) {


	}
	*/

	keep_window_open(".");
}

catch (runtime_error e) {
	cout << e.what() << "\n";
	keep_window_open(".");
}
catch (...) {
	cout << "Exiting!\n";
	keep_window_open(".");
}
Output:
Enter sentece to be checked or x to exit:
birds fly and fish swim.
OK!
x for exit or continue:
C++ rules.
OK!
x for exit or continue:
x
Please enter . to exit

using a simple class

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

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 6 Exercise 4

#include "std_lib_facilities.h"

class nameValue {
public:
	nameValue(string n, int a) : name(n), age(a) { }
	string name;
	int age;
};

int main()
try
{
	vector<nameValue> nameAndAge;

	string nameTemp;
	int ageTemp;

	bool check = true;

	while (check == true) {
		cout << "Enter name and age pairs to be collected, or 'noname' and '0' to end the entry.\n";
		if (cin >> nameTemp >> ageTemp) {
			if (nameTemp == "noname" && ageTemp == 0) {
				check = false;
			}
			else {
				for (int i = 0; i < nameAndAge.size(); i++) {
					if (nameAndAge[i].name == nameTemp) {
						error("This name already exists ", nameTemp);
					}
				}
				nameAndAge.push_back(nameValue(nameTemp, ageTemp));
			}
		}
		else {
			error("Bad input");
		}
	}

	for (int i = 0; i < nameAndAge.size(); i++) {
		cout << "Name: " << nameAndAge[i].name << " Score: " << nameAndAge[i].age << "\n";
	}

	keep_window_open(".");
}

catch (runtime_error e) {
	cout << e.what() << "\n";
	keep_window_open(".");
}
catch (...) {
	cout << "Exiting \n";
	keep_window_open(".");
}

/*class Name_value {	// much like Token from 6.3.3
public:
	Name_value(string n, int s): name(n), score(s) { }
	string name;
	int score;
};

int main()
try
{
	vector<Name_value> pairs;

	string n;
	int v;

	while (cin>>n>>v && n!="NoName") {	// read string int pair
		for (int i=0; i<pairs.size(); ++i)
			if (n==pairs[i].name) error("duplicate: ",n); // chek for duplicate
		pairs.push_back(Name_value(n,v));
	}

	for (int i=0; i<pairs.size(); ++i)
			cout << '(' << pairs[i].name << ',' << pairs[i].score << ")\n";

	keep_window_open("~");	// For some Windows(tm) setups
	}*/

calculator 1.3 [adding factorial]

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

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 6 Exercise 3

#include "std_lib_facilities.h" //ERROR: "#include "../std_lib_facilities.h", instead #include "std_lib_facilities.h"

//------------------------------------------------------------------------------

class Token { //ERROR 1/5: "lass Token{", missing c for class
public:
	char kind;        // what kind of token
	double value;     // for numbers: a value 
	Token(char ch)    // make a Token from a char
		:kind(ch), value(0) { }
	Token(char ch, double val)     // make a Token from a char and a double
		:kind(ch), value(val) { }
};

//------------------------------------------------------------------------------

class Token_stream {
public:
	Token_stream();   // make a Token_stream that reads from cin
	Token get();      // get a Token (get() is defined elsewhere)
	void putback(Token t);    // put a Token back
private:
	bool full;        // is there a Token in the buffer?
	Token buffer;     // here is where we keep a Token put back using putback()
};

//------------------------------------------------------------------------------

// The constructor just sets full to indicate that the buffer is empty:
Token_stream::Token_stream()
	:full(false), buffer(0)    // no Token in buffer
{
}

//------------------------------------------------------------------------------

// The putback() member function puts its argument back into the Token_stream's buffer:
void Token_stream::putback(Token t)
{
	if (full) error("putback() into a full buffer");
	buffer = t;       // copy t to buffer
	full = true;      // buffer is now full
}

//------------------------------------------------------------------------------

Token Token_stream::get() //ERROR 2/5: "Token get()", instead Token Token_stream::get()
{
	if (full) {       // do we already have a Token ready?
					  // remove token from buffer
		full = false;
		return buffer;
	}

	char ch;
	cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)

	switch (ch) {
	case '=':    // for "print"
	case 'x':    // for "quit"
	case '(': case ')': case '{': case '}': case '+': case '-': case '*': case '/': case '!':
		return Token(ch);        // let each character represent itself
	case '.':
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9': //ERROR 1/3: "case'8':", missing
	{
		cin.putback(ch);         // put digit back into the input stream
		double val;
		cin >> val;              // read a floating-point number
		return Token('8', val);   // let '8' represent "a number"
	}
	default:
		error("Bad token");
	}
}

//------------------------------------------------------------------------------

Token_stream ts;        // provides get() and putback() 

						//------------------------------------------------------------------------------

double expression();    // declaration so that primary() can call expression()

						//------------------------------------------------------------------------------

						// deal with numbers and parentheses
double primary()
{
	Token t = ts.get();
	switch (t.kind) {

	case '(':     // handle '(' expression ')'
	{
		double d = expression();
		t = ts.get();
		if (t.kind != ')') error("')' expected )"); //ERROR 3/5: "if (t.kind != ')') error("')' expected)", missing );
		return d;
	}

	case '{':     // handle '(' expression ')'
	{
		double d = expression();
		t = ts.get();
		if (t.kind != '}') error("'}' expected }"); //ERROR 3/5: "if (t.kind != ')') error("')' expected)", missing );
		return d;
	}

	case '8':            // we use '8' to represent a number
		return t.value;  // return the number's value

	default:
		error("primary expected");
	}
}

//------------------------------------------------------------------------------

// deal with !
double factorial()
{
	double left = primary();
	Token t = ts.get();        // get the next token from token stream

	while (true) {
		switch (t.kind) {
		case '!':
		{
			int leftVal = left;
			for (int i = 1; i < leftVal; i++) {
				left *= i;
			}
			t = ts.get();
			break;
		}
		default:
			ts.putback(t);     // put t back into the token stream
			return left;
		}
	}
}

//------------------------------------------------------------------------------

// deal with *, /, and %
double term()
{
	double left = factorial();
	Token t = ts.get();        // get the next token from token stream

	while (true) {
		switch (t.kind) {
		case '*':
		{
			left *= factorial();
			t = ts.get();
			break;
		}
		case '/':
		{
			double d = factorial();
			if (d == 0) error("divide by zero");
			left /= d;
			t = ts.get();
			break;
		}
		default:
			ts.putback(t);     // put t back into the token stream
			return left;
		}
	}
}

//------------------------------------------------------------------------------

// deal with + and -
double expression()
{
	double left = term();      // read and evaluate a Term //ERROR 4/5: "double left = term(;" mssing )
	Token t = ts.get();        // get the next token from token stream

	while (true) {
		switch (t.kind) {
		case '+':
			left += term();    // evaluate Term and add
			t = ts.get();
			break; //ERROR 2/3: "break;", missing
		case '-':
			left -= term();    // evaluate Term and subtract //ERROR 3/3: "left += term();" plus instead of minus
			t = ts.get();
			break;
		default:
			ts.putback(t);     // put t back into the token stream
			return left;       // finally: no more + or -: return the answer
		}
	}
}

//------------------------------------------------------------------------------

int main()
try
{
	cout << "Welcome to our simple calculator.\n";
	cout << "Please enter expressions using floating-point numbers.\n";
	cout << "Currently available operators are: '(', ')', '*', '/', '+', '-' and '!'.\n";
	cout << "Use '=' to get result or 'x' to quit the program.\n";

	double val = 0; //ERROR 5/5: val not initialized

	while (cin) {
		Token t = ts.get();

		if (t.kind == 'x') break; // 'x' for quit
		if (t.kind == '=')        // ';' for "print now"
			cout << "=" << val << '\n';
		else
			ts.putback(t);
		val = expression();
	}
	keep_window_open();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}
catch (...) {
	cerr << "Oops: unknown exception!\n";
	keep_window_open();
	return 2;
}

//------------------------------------------------------------------------------
Output:
Welcome to our simple calculator.
Please enter expressions using floating-point numbers.
Currently available operators are: '(', ')', '*', '/', '+', '-' and '!'.
Use '=' to get result or 'x' to quit the program.
13!
=
=6.22702e+09

calculator 1.3 [adding curly brakets]

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

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 6 Exercise 2

//input: {4 + 3} / 3;

#include "std_lib_facilities.h" //ERROR: "#include "../std_lib_facilities.h", instead #include "std_lib_facilities.h"

//------------------------------------------------------------------------------

class Token { //ERROR 1/5: "lass Token{", missing c for class
public:
	char kind;        // what kind of token
	double value;     // for numbers: a value 
	Token(char ch)    // make a Token from a char
		:kind(ch), value(0) { }
	Token(char ch, double val)     // make a Token from a char and a double
		:kind(ch), value(val) { }
};

//------------------------------------------------------------------------------

class Token_stream {
public:
	Token_stream();   // make a Token_stream that reads from cin
	Token get();      // get a Token (get() is defined elsewhere)
	void putback(Token t);    // put a Token back
private:
	bool full;        // is there a Token in the buffer?
	Token buffer;     // here is where we keep a Token put back using putback()
};

//------------------------------------------------------------------------------

// The constructor just sets full to indicate that the buffer is empty:
Token_stream::Token_stream()
	:full(false), buffer(0)    // no Token in buffer
{
}

//------------------------------------------------------------------------------

// The putback() member function puts its argument back into the Token_stream's buffer:
void Token_stream::putback(Token t)
{
	if (full) error("putback() into a full buffer");
	buffer = t;       // copy t to buffer
	full = true;      // buffer is now full
}

//------------------------------------------------------------------------------

Token Token_stream::get() //ERROR 2/5: "Token get()", instead Token Token_stream::get()
{
	if (full) {       // do we already have a Token ready?
					  // remove token from buffer
		full = false;
		return buffer;
	}

	char ch;
	cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)

	switch (ch) {
	case '=':    // for "print"
	case 'x':    // for "quit"
	case '(': case ')': case '{': case '}': case '+': case '-': case '*': case '/':
		return Token(ch);        // let each character represent itself
	case '.':
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9': //ERROR 1/3: "case'8':", missing
	{
		cin.putback(ch);         // put digit back into the input stream
		double val;
		cin >> val;              // read a floating-point number
		return Token('8', val);   // let '8' represent "a number"
	}
	default:
		error("Bad token");
	}
}

//------------------------------------------------------------------------------

Token_stream ts;        // provides get() and putback() 

						//------------------------------------------------------------------------------

double expression();    // declaration so that primary() can call expression()

						//------------------------------------------------------------------------------

						// deal with numbers and parentheses
double primary()
{
	Token t = ts.get();
	switch (t.kind) {

	case '(':     // handle '(' expression ')'
	{
		double d = expression();
		t = ts.get();
		if (t.kind != ')') error("')' expected)"); //ERROR 3/5: "if (t.kind != ')') error("')' expected)", missing );
		return d;
	}

	case '{':     // handle '(' expression ')'
	{
		double d = expression();
		t = ts.get();
		if (t.kind != '}') error("'}' expected)"); //ERROR 3/5: "if (t.kind != ')') error("')' expected)", missing );
		return d;
	}

	case '8':            // we use '8' to represent a number
		return t.value;  // return the number's value

	default:
		error("primary expected");
	}
}

//------------------------------------------------------------------------------

// deal with *, /, and %
double term()
{
	double left = primary();
	Token t = ts.get();        // get the next token from token stream

	while (true) {
		switch (t.kind) {
		case '*':
			left *= primary();
			t = ts.get();
			break;
		case '/':
		{
			double d = primary();
			if (d == 0) error("divide by zero");
			left /= d;
			t = ts.get();
			break;
		}
		default:
			ts.putback(t);     // put t back into the token stream
			return left;
		}
	}
}

//------------------------------------------------------------------------------

// deal with + and -
double expression()
{
	double left = term();      // read and evaluate a Term //ERROR 4/5: "double left = term(;" mssing )
	Token t = ts.get();        // get the next token from token stream

	while (true) {
		switch (t.kind) {
		case '+':
			left += term();    // evaluate Term and add
			t = ts.get();
			break; //ERROR 2/3: "break;", missing
		case '-':
			left -= term();    // evaluate Term and subtract //ERROR 3/3: "left += term();" plus instead of minus
			t = ts.get();
			break;
		default:
			ts.putback(t);     // put t back into the token stream
			return left;       // finally: no more + or -: return the answer
		}
	}
}

//------------------------------------------------------------------------------

int main()
try
{
	cout << "Welcome to our simple calculator.\n";
	cout << "Please enter expressions using floating-point numbers.\n";
	cout << "Currently available operators are: '(', ')', '*', '/', '+' and '-'.\n";
	cout << "Use '=' to get result or 'x' to quit the program.\n";

	double val = 0; //ERROR 5/5: val not initialized

	while (cin) {
		Token t = ts.get();

		if (t.kind == 'x') break; // 'x' for quit
		if (t.kind == '=')        // ';' for "print now"
			cout << "=" << val << '\n';
		else
			ts.putback(t);
		val = expression();
	}
	keep_window_open();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}
catch (...) {
	cerr << "Oops: unknown exception!\n";
	keep_window_open();
	return 2;
}

//------------------------------------------------------------------------------
Output:
{4 + 3} / 3;
=2.33333

calculator 1.2 [bug fixes]

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

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 6 Drill

//
// This is example code from Chapter 6.7 "Trying the second version" of
// "Software - Principles and Practice using C++" by Bjarne Stroustrup
//

/*
This file is known as calculator02buggy.cpp

I have inserted 5 errors that should cause this not to compile
I have inserted 3 logic errors that should cause the program to give wrong results

First try to find an remove the bugs without looking in the book.
If that gets tedious, compare the code to that in the book (or posted source code)

Happy hunting!

*/

//input: (4 + 3) / 3;

#include "std_lib_facilities.h" //ERROR: "#include "../std_lib_facilities.h", instead #include "std_lib_facilities.h"

//------------------------------------------------------------------------------

class Token{ //ERROR 1/5: "lass Token{", missing c for class
public:
	char kind;        // what kind of token
	double value;     // for numbers: a value 
	Token(char ch)    // make a Token from a char
		:kind(ch), value(0) { }
	Token(char ch, double val)     // make a Token from a char and a double
		:kind(ch), value(val) { }
};

//------------------------------------------------------------------------------

class Token_stream {
public:
	Token_stream();   // make a Token_stream that reads from cin
	Token get();      // get a Token (get() is defined elsewhere)
	void putback(Token t);    // put a Token back
private:
	bool full;        // is there a Token in the buffer?
	Token buffer;     // here is where we keep a Token put back using putback()
};

//------------------------------------------------------------------------------

// The constructor just sets full to indicate that the buffer is empty:
Token_stream::Token_stream()
	:full(false), buffer(0)    // no Token in buffer
{
}

//------------------------------------------------------------------------------

// The putback() member function puts its argument back into the Token_stream's buffer:
void Token_stream::putback(Token t)
{
	if (full) error("putback() into a full buffer");
	buffer = t;       // copy t to buffer
	full = true;      // buffer is now full
}

//------------------------------------------------------------------------------

Token Token_stream::get() //ERROR 2/5: "Token get()", instead Token Token_stream::get()
{
	if (full) {       // do we already have a Token ready?
					  // remove token from buffer
		full = false;
		return buffer;
	}

	char ch;
	cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)

	switch (ch) {
	case '=':    // for "print"
	case 'x':    // for "quit"
	case '(': case ')': case '+': case '-': case '*': case '/':
		return Token(ch);        // let each character represent itself
	case '.':
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9': //ERROR 1/3: "case'8':", missing
	{
		cin.putback(ch);         // put digit back into the input stream
		double val;
		cin >> val;              // read a floating-point number
		return Token('8', val);   // let '8' represent "a number"
	}
	default:
		error("Bad token");
	}
}

//------------------------------------------------------------------------------

Token_stream ts;        // provides get() and putback() 

						//------------------------------------------------------------------------------

double expression();    // declaration so that primary() can call expression()

						//------------------------------------------------------------------------------

						// deal with numbers and parentheses
double primary()
{
	Token t = ts.get();
	switch (t.kind) {
	case '(':    // handle '(' expression ')'
	{
		double d = expression();
		t = ts.get();
		if (t.kind != ')') error("')' expected)"); //ERROR 3/5: "if (t.kind != ')') error("')' expected)", missing );
			return d;
	}
	case '8':            // we use '8' to represent a number
		return t.value;  // return the number's value
	default:
		error("primary expected");
	}
}

//------------------------------------------------------------------------------

// deal with *, /, and %
double term()
{
	double left = primary();
	Token t = ts.get();        // get the next token from token stream

	while (true) {
		switch (t.kind) {
		case '*':
			left *= primary();
			t = ts.get();
			break;
		case '/':
		{
			double d = primary();
			if (d == 0) error("divide by zero");
			left /= d;
			t = ts.get();
			break;
		}
		default:
			ts.putback(t);     // put t back into the token stream
			return left;
		}
	}
}

//------------------------------------------------------------------------------

// deal with + and -
double expression()
{
	double left = term();      // read and evaluate a Term //ERROR 4/5: "double left = term(;" mssing )
	Token t = ts.get();        // get the next token from token stream

	while (true) {
		switch (t.kind) {
		case '+':
			left += term();    // evaluate Term and add
			t = ts.get();
			break; //ERROR 2/3: "break;", missing
		case '-':
			left -= term();    // evaluate Term and subtract //ERROR 3/3: "left += term();" plus instead of minus
			t = ts.get();
			break;
		default:
			ts.putback(t);     // put t back into the token stream
			return left;       // finally: no more + or -: return the answer
		}
	}
}

//------------------------------------------------------------------------------

int main()
try
{
	cout << "Welcome to our simple calculator.\n";
	cout << "Please enter expressions using floating-point numbers.\n";
	cout << "Currently available operators are: '(', ')', '*', '/', '+' and '-'.\n";
	cout << "Use '=' to get result or 'x' to quit the program.\n";

	double val = 0; //ERROR 5/5: val not initialized

	while (cin) {
		Token t = ts.get();

		if (t.kind == 'x') break; // 'x' for quit
		if (t.kind == '=')        // ';' for "print now"
			cout << "=" << val << '\n';
		else
			ts.putback(t);
		val = expression();
	}
	keep_window_open();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}
catch (...) {
	cerr << "Oops: unknown exception!\n";
	keep_window_open();
	return 2;
}

//------------------------------------------------------------------------------
Output:
(4 + 3) / 3;
=2.33333

calculator 1.2

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 6 Try This Page 216
Using std_lib_facilities.h by Bjarne Stroustrup.

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 6 Try This Page 216

#include "std_lib_facilities.h"

class Token {
public:
	char kind;        // what kind of token
	double value;     // for numbers: a value 
	Token(char ch)    // make a Token from a char
		:kind(ch), value(0) { }
	Token(char ch, double val)     // make a Token from a char and a double
		:kind(ch), value(val) { }
};

class Token_stream {
public:
	Token_stream();   // make a Token_stream that reads from cin
	Token get();      // get a Token (get() is defined elsewhere)
	void putback(Token t);    // put a Token back
private:
	bool full;        // is there a Token in the buffer?
	Token buffer;     // here is where we keep a Token put back using putback()
};

// The constructor just sets full to indicate that the buffer is empty:
Token_stream::Token_stream()
	:full(false), buffer(0)    // no Token in buffer
{
}

// The putback() member function puts its argument back into the Token_stream's buffer:
void Token_stream::putback(Token t)
{
	if (full) error("putback() into a full buffer");
	buffer = t;       // copy t to buffer
	full = true;      // buffer is now full
}

Token Token_stream::get()
{
	if (full) {       // do we already have a Token ready?
					  // remove token from buffer
		full = false;
		return buffer;
	}

	char ch;
	cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)

	switch (ch) {
	case ';':    // for "print"
	case 'q':    // for "quit"
	case '(': case ')': case '+': case '-': case '*': case '/':
		return Token{ ch };        // let each character represent itself
	case '.':
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	{
		cin.putback(ch);         // put digit back into the input stream
		double val;
		cin >> val;              // read a floating-point number
		return Token{ '8', val };   // let '8' represent "a number"
	}
	default:
		error("Bad token");
	}
}

Token_stream ts;        // provides get() and putback() 
double expression();    // declaration so that primary() can call expression()

// deal with numbers and parentheses
double primary()
{
	Token t = ts.get();
	switch (t.kind) {
	case '(':    // handle '(' expression ')'
	{
		double d = expression();
		t = ts.get();
		if (t.kind != ')') error("')' expected");
		return d;
	}
	case '8':            // we use '8' to represent a number
		return t.value;  // return the number's value
	default:
		error("primary expected");
	}
}

// deal with *, /, and %
double term()
{
	double left = primary();
	Token t = ts.get();        // get the next token from token stream

	while (true) {
		switch (t.kind) {
		case '*':
			left *= primary();
			t = ts.get();
			break;
		case '/':
		{
			double d = primary();
			if (d == 0) error("divide by zero");
			left /= d;
			t = ts.get();
			break;
		}
		default:
			ts.putback(t);     // put t back into the token stream
			return left;
		}
	}
}

// deal with + and -
double expression()
{
	double left = term();      // read and evaluate a Term
	Token t = ts.get();        // get the next token from token stream

	while (true) {
		switch (t.kind) {
		case '+':
			left += term();    // evaluate Term and add
			t = ts.get();
			break;
		case '-':
			left -= term();    // evaluate Term and subtract
			t = ts.get();
			break;
		default:
			ts.putback(t);     // put t back into the token stream
			return left;       // finally: no more + or -: return the answer
		}
	}
}

int main()
try
{
	/* First Version of 6.7
	while (cin)
	cout << "=" << expression() << '\n';
	keep_window_open("~0");
	*/

	double val = 0;
	while (cin) {
		Token t = ts.get();

		if (t.kind == 'q') break; // 'q' for quit
		if (t.kind == ';')        // ';' for "print now"
			cout << "=" << val << '\n';
		else
			ts.putback(t);
		val = expression();
	}
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	return 1;
}
catch (...) {
	cerr << "Oops: unknown exception!\n";
	return 2;
}
Output:
4 + 6;
=10
10 - 3
;
=7