I'm writing a program that will balance Chemistry Equations; I thought it'd be a good challenge and help reinforce the information I've recently learned.

My program is set up to use getline(cin, std::string) to receive the equation. From there it separates the equation into two halves: a left side and right side by making a substring when it encounters a =.

I'm having issues which only concerns the left side of my string, which is called std::string leftSide. My program then goes into a for loop that iterates over the length of leftSide. The first condition checks to see if the character is uppercase, because chemical formulas are written with the element symbols and a symbol consists of either one upper case letter, or an upper case and one lower case letter. After it checks to see if the current character is uppercase, it checks to see if the next character is lower case; if it's lower case then I create a temporary string, combine leftSide[index] with leftSide[index+1] in the temp string then push the string to my vector.

My problem lies on the first iteration; I've been using CuFe3 = 8 (right side doesn't matter right now) to test it out. The only thing stored in std::string temp is C. I'm not sure why this happening; also, I'm still getting numbers in my final answer and I don't understand why. Some help fixing these two issues, along with an explanation, would be greatly appreciated.

[CODE]

int index = 0;
    for (it = leftSide.begin(); it!=leftSide.end(); ++it, index++)
    {
        bool UPPER_LETTER = isupper(leftSide[index]);
        bool NEXT_LOWER_LETTER = islower(leftSide[index+1]);
        if (UPPER_LETTER)// if the character is an uppercase letter
        {
            if (NEXT_LOWER_LETTER)
            {
                string temp = leftSide.substr(index, (index+1));//add THIS capital and next lowercase
                elementSymbol.push_back(temp); // add temp to vector
                temp.clear(); //used to try and fix problem initially
            }

            else if (UPPER_LETTER && !NEXT_LOWER_LETTER) //used to try and prevent number from getting in
            {
                string temp = leftSide.substr(index, index);
                elementSymbol.push_back(temp);
            }
        }
        else if (isdigit(leftSide[index])) // if it's a number
            num++;

    }

[EDIT] When I entered in only ASDF, *** ***S ***DF ***F was the output.

有帮助吗?

解决方案

string temp = leftSide.substr(index, (index+1));

substr takes the first index and then a length, rather than first and last indices. You want substr(index, 2). Since in your example index is 0 you're doing: substr(index, 1) which creates a string of length 1, which is "C".

string temp = leftSide.substr(index, index);

Since index is 0 this is substr(index, 0), which creates a string of length 0, that is, an empty string.

When you're processing parts of the string with a higher index, such as Fe in "CuFe3" the value you pass in as the length parameter is higher and so you're creating strings that are longer. F is at index 2 and you call substr(index, 3), which creates the string "Fe3".

Also the standard library usually uses half open ranges, so even if substr took two indices (which, again, it doesn't) you would do substr(index, index+2) to get a two character string.

bool NEXT_LOWER_LETTER = islower(leftSide[index+1]);

You might want to check that index+1 is a valid index. If you don't want to do that manually you might at least switch to using the bounds checked function at() instead of operator[].

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top