converting chemical substance string to int using mass of atoms

116 Views Asked by At

i try to make a program that calculate a mass of chemical substance that you put into it. i got stuck on converting string to int to do the math. every time i try to convert i got an error. I am using visual studio 2022 comunity.

here is code that i have:

and in function "Obliczenia()" i am trying to convert string to int and nothing works as i want. mainly becuse I put string using characters and numbers but converting every element to its mass form is hard for me too and can't do that;

#include <string>
#include <iostream>
#include <conio.h>
#include <vector>
using namespace std;

string substancja = "";
#define H 1;
#define He 4;
#define Li 7;
#define Be 9;
#define B 11;
#define C 12;
#define N 14;
#define O 16;
#define F 19;
#define Ne 20;
#define Na 23;
#define Mg 24;
#define Al 17;
#define Si 28;
#define P 31;
#define S 32;
#define Cl 35;
#define Ar 40;
#define K 39;
#define Ca 40;
#define Sc 45;
#define Ti 48;
#define V 51;
#define Cr 52;
#define Mn 55;
#define Fe 56;
#define Co 59;
#define Ni 59;
#define Cu 64;
#define Zn 65;
#define Ga 70;
#define Ge 73;
#define As 75;
#define Se 79;
#define Br 80;
#define Kr 84;
#define Rb 85;
#define Sr 88;
#define Y 89;
#define Zr 91;
#define Nb 93;
#define Mo 96;
#define Tc 98;
#define Ru 101;
#define Rh 103;
#define Pd 106;
#define Ag 108;
#define Cd 112;
#define In 115;
#define Sn 119;
#define Sb 122;
#define Te 128;
#define I 127;
#define Xe 131;
#define Cs 133;
#define Ba 137;
#define La 139;
#define Ce 140;
#define Pr 141;
#define Nd 144;
#define Pm 145;
#define Sm 150;
#define Eu 152;
#define Gd 157;
#define Tb 159;
#define Dy 163;
#define Ho 165;
#define Er 167;
#define Tm 169;
#define Yb 173;
#define Lu 175;
#define Hf 178;
#define Ta 181;
#define W 184;
#define Re 186;
#define Os 190;
#define Ir 192;
#define Pt 195;
#define Au 197;
#define Hg 201;
#define Tl 204;
#define Pb 207;
#define Bi 209;
#define Po 209;
#define At 209;
#define Rn 222;
#define Fr 223;
#define Ra 226;
#define Ac 227;
#define Th 232;
#define Pa 231;
#define U 238;
#define Np 237;
#define Pu 244;
#define Am 243;
#define Cm 247;
#define Bk 247;
#define Cf 251;
#define Es 252;
#define Fm 257;
#define Md 258;
#define No 259;
#define Lr 262;
#define Rf 261;
#define Db 263;
#define Sg 265;
#define Bh 264;
#define Hs 269;
#define Mt 268;
#define Ds 281;
#define Rg 280;
#define Cn 285;
#define Nh 284;
#define Fl 289;
#define Mc 288;
#define Lv 292;
#define Ts 294;
#define Og 294;

int obliczenia(string sub)
{
    int wynik;
    vector<int> ilosc(sub.size());
    int dlg;

    for (int i = 0; i < sub.size(); i++)
    {
        ilosc[i] = sub[i];
    }
    /*
    for(int i = 0; i<sub.length(); i++)
        if (i > 0)
        {
            if (sub[i] == 'H')
            {
                sub[i] = H;
                sub[i] += '+';
            }
            else if (sub[i] == 'He')
            {
                sub[i] = He;
                sub[i] += '+';
            }
            else if (sub[i] == 'Li')
            {
                sub[i] = Li;
                sub[i] += '+';
            }
            else if (sub[i] == 'Be')
            {
                sub[i] = Be;
                sub[i] += '+';
            }
            else if (sub[i] == 'B')
            {
                sub[i] = B;
                sub[i] += '+';
            }
            else if (sub[i] == 'C')
            {
                sub[i] = C;
                sub[i] += '+';
            }
            else if (sub[i] == 'N')
            {
                sub[i] = N;
                sub[i] += '+';
            }
            else if (sub[i] == 'O')
            {
                sub[i] = O;
                sub[i] += '+';
            }
            else if (sub[i] == 'F')
            {
                sub[i] = F;
                sub[i] += '+';
            }
            else if (sub[i] == 'Ne')
            {
                sub[i] = Ne;
                sub[i] += '+';
            }
        }
        */
    dlg = stoi(sub);
    cout << dlg;
    return 0;
}

int main()
{
    setlocale(LC_ALL, "");
    int wynik;
    cout << "Podaj wzory substancji chemicznej (przykład H2SO4): " << endl;
    cin >> substancja;
    cout << substancja;
    wynik = obliczenia(substancja);

}
1

There are 1 best solutions below

0
Ted Lyngmo On

Your current approach is very cumbersome. I suggest that you use a std::map in which you can lookup the atomic mass from the element symbols:

#include <map>
#include <string_view>

static const std::map<std::string_view, int> el_am{
    {"H", 1},    {"He", 4},   {"Li", 7},   {"Be", 9},   {"B", 11},
    //...
};

Then you need a parsing function to breakdown H2O and similar strings. Here's one way to extract a symbol and its multiplier:

  • Create an iterator to the beginning of the symbol to be extracted.
    • Use a second iterator to find where the symbol ends. That is, when there are no more lowercase letters or the string is depleted.
    • When that is done, you have an iterator to the beginning and to the end of your symbol. Create a std::string_view and look up the mass in the std::map.
  • Then parse as many digits that follows. For this, you can use std::from_chars which will return a result with a pointer to where the parsing stopped.
  • You now have the mass and the multiplier. Add the product to a total_mass variable.
  • Repeat until the whole string is depleted.

Example:

#include <algorithm>
#include <cctype>
#include <charconv>

int parse(std::string_view str) {
    int total_mass = 0;

    // loop from start to end of the string:
    for (const char *it = str.data(), *const end = it + str.size(); it != end;)
    {
        // extract the symbol
        const char* start = it;

        // find the first non-lowercase char, ignoring the first (start + 1)
        it = std::find_if_not(start + 1, end, [](unsigned char ch) -> bool {
            return std::islower(ch);
        });

        std::string_view sym{start, it}; // create sym from the two iterators
        
        // look up the mass for the symbol
        int this_mass = el_am.at(sym);

        // extract the multiplier
        int mul = 1;
        auto res = std::from_chars(it, end, mul);

        // set `it` to point where from_chars stopped parsing digits
        it = res.ptr;
        std::cout << ' ' << sym << '(' << this_mass << ") x " << mul << '\n'; // debug

        // add the mass for this element multiplied with the multiplier
        total_mass += this_mass * mul;
    }
    return total_mass;
}

Demo