#include #include #include using namespace std; struct input { string line; int pos, len; // function inside struct // no return type // same name as struct // is an automatic constructor input() { line = ""; pos = 0; len = 0; } void fill(string s) { line = s; pos = 0; len = s.length(); } void print() { cout << "line is '" << line << "'\n"; cout << "pos is " << pos << "\n"; cout << "len is " << len << "\n"; } char next() { if (pos >= len) { pos += 1; return '\n'; } char result = line[pos]; pos += 1; return result; } void un_next() { if (pos <= 0) return; pos -= 1; } char sneak() { char x = next(); un_next(); return x; } }; char whats_next(input & x) { char s = x.sneak(); if (s >= 'A' && s <='Z') return 'A'; // an Atom is coming next if (s >= '0' && s <='9') return 'N'; // a Number is coming next if (s == '\n') return 'E'; // End of formula is next return s; } string read_atom(input & x) { string s = ""; char c1 = x.next(); if (c1 < 'A' || c1 > 'Z') { cout << "Capital expected at beginning of atom\n"; return "XXXXXX"; } s += c1; char c2 = x.next(); if (c2 >= 'a' && c2 <= 'z') return s + c2; x.un_next(); return s; } int read_number(input & x) { int value = 0; while (true) { char c = x.next(); if (c < '0' || c > '9') break; value = value * 10 + c - '0'; } x.un_next(); return value; } struct element { string symbol, name; int at_no; double at_wt; }; void print(element e) { cout << e.at_no << ": " << e.symbol << ", " << e.name << ", at wt = " << e.at_wt << "\n"; } const int max_num_els = 110; element table[max_num_els]; int num_els = 0; void read_table(ifstream & f) { while (num_els < max_num_els) { f >> table[num_els+1].symbol >> table[num_els+1].name >> table[num_els+1].at_wt; table[num_els+1].at_no = num_els + 1; if (f.fail()) return; num_els += 1; } } int find(string sy) { for (int i = 1; i <= num_els; i += 1) if (table[i].symbol == sy) return i; return 0; } double compute_formula(input & I) { double prev_wt = 0.0, total = 0.0; while (true) { char nx = whats_next(I); if (nx == 'A') // an atom { string at = read_atom(I); int epos = find(at); if (epos < 1) { cout << "element " << at << " not known\n"; break; } print(table[epos]); prev_wt = table[epos].at_wt; total += prev_wt; } else if (nx == 'N') // a number { int n = read_number(I); total += (n - 1) * prev_wt; cout << " correcting " << prev_wt << " to " << n * prev_wt << "\n"; } else if (nx == '(') { I.next(); double subtotal = compute_formula(I); cout << "subtotal is " << subtotal << "\n"; prev_wt = subtotal; total += prev_wt; } else if (nx == ')') // end of sub-formula { I.next(); break; } else if (nx == 'E') // end of input break; else { cout << "Bad input: '" << nx << "'\n"; break; } } return total; } int main() { ifstream file("table.txt"); if (file.fail()) { cout << "Can't read table file\n"; exit(1); } read_table(file); file.close(); cout << num_els << " elements read\n"; input I; string s; cout << "Enter a line: "; getline(cin, s); I.fill(s); double total = compute_formula(I); cout << "--------------------------------------\n"; cout << "Molecular weight = " << total << "\n"; cout << "--------------------------------------\n"; }