#include #include #include using namespace std; struct element { int atno; string sym, name; double atwt; element(int an, string sy, string nm, double aw) { atno = an; sym = sy; name = nm; atwt = aw; } element() { atno = 0; sym = ""; name = ""; atwt = 0; } void print() { cout << "(" << atno << ", " << atno << ", '" << sym << "', '" << name << "', " << atwt << ")"; } }; element makeel(int an, string sy, string nm, double aw) { element e; e.atno = an; e.sym = sy; e.name = nm; e.atwt = aw; return e; } int read_table(element pt[]) { ifstream inf; inf.open("/home/www/class/een118/a3010b.txt"); if (inf.fail()) { cerr << "Can't open file\n"; exit(1); } int atno = 0; while (true) { string sym, name; double atwt; inf >> sym >> name >> atwt; if (inf.fail()) break; atno += 1; element e(atno, sym, name, atwt); pt[atno] = e; } pt[0] = makeel(0, "XXX", "XXXXXXXXX", 0.0); inf.close(); return atno; } element findel(string sy, element pt[], int n) { for (int i = 1; i <= n; i += 1) if (pt[i].sym == sy) return pt[i]; return pt[0]; } string get_symbol() // must only be called is next char is known to be a capital letter { char c1 = cin.get(); char c2 = cin.peek(); if (c2 < 'a' || c2 > 'z') return string("") + c1; cin.get(); return string("") + c1 + c2; } int get_number() // must only be called if next char is know to be a digit { int value = 0; while (true) { char c = cin.peek(); if (c < '0' || c > '9') return value; cin.get(); value = value * 10 + c - '0'; } } string int_to_string(int n) { string result = ""; if (n > 9) result = int_to_string(n / 10); result += (char)('0' + n % 10); return result; } struct combination { string s; double d; }; combination read_formula(element pt[], int entries, bool sub, string indent) { double molwt = 0, atwt; string sym, whole_thing = ""; while (true) { char nxt = cin.peek(); if (cin.fail()) break; if (nxt == '\n') { cin.get(); if (sub) cerr << "unmatched (\n"; break; } else if (nxt == ')') { cin.get(); if (! sub) cerr << "extra )\n"; combination p; p.d = molwt; p.s = whole_thing; return p; } else if (nxt == '(') { cin.get(); combination part = read_formula(pt, entries, true, indent + " "); sym = part.s; whole_thing = whole_thing + "(" + sym + ")"; atwt = part.d; } else if (nxt < 'A' || nxt > 'Z') { cout << "Element symbol expected but '" << nxt << "' seen\n"; break; } else { sym = get_symbol(); element e = findel(sym, pt, entries); if (e.atno == 0) { cout << "No element has symbol '" << sym << "'\n"; break; } whole_thing = whole_thing + sym; atwt = e.atwt; } int mult = 1; nxt = cin.peek(); if (nxt >= '0' && nxt <= '9') { mult = get_number(); whole_thing = whole_thing + int_to_string(mult); } cout << indent << sym << " (" << atwt << ") x " << mult << " = " << atwt * mult << "\n"; molwt += atwt * mult; } combination p; p.d = molwt; p.s = whole_thing; return p; } int main() { string sym, name; double atwt; element pt[120]; int atno = read_table(pt); const int entries = atno; for (atno = 1; atno <= entries; atno += 1) { pt[atno].print(); cout << "\n"; } while (true) { cout << "> "; combination p = read_formula(pt, entries, false, " "); if (cin.fail()) { cout << "\n"; break; } double mw = p.d; cout << "Molecular weight for " << p.s << " is " << mw << "\n"; } }