I'm working on a program to write chemical reactions a certain way from a file, calculate the mass and check whether they are conserved.

I have this code so far:

#include <iostream>
#include <fstream>			
#include <string>			
#include <sstream>			

using namespace std;

#define INDEX_H 0
#define INDEX_B 1
#define INDEX_C 2
#define INDEX_N 3
#define INDEX_O 4
#define INDEX_F 5

#define DIFF_ATOMS 6

const char atom[] = {'H', 'B', 'C', 'N', 'O', 'F'};
const double mass[] = {1.008, 10.811, 12.011, 14.007, 15.999, 18.998};

typedef int molecule[DIFF_ATOMS];

//Function prototypes
void parse_reaction(istream& fin);
void reset_moleculen(molecule m);
void parse_molecule(string part, molecule m);
void check_reaction(molecule left_side, molecule right_side);



/*----------------------------------------------------*/
//Main program
int main()
{
	//Declaration
		
	string filename;
	ifstream fin;
	
	//Open file
	cout << "Insert the name of the file: ";
	cin >> filename;
	
	fin.open(filename.c_str());
	if(fin.fail())
	{
		cerr << "Error opening file";
		exit(1);
	}
	
	parse_reaction(fin);
	
	//Close file
	fin.close();
	
    system("PAUSE");
    
    return 0;
}



/*----------------------------------------------------*/
//Function for checking the reaction
void parse_reaction(istream& fin)
{
	string part;
	int i;
	molecule left_side, right_side, *pside_counter;
	
	//Reset values of the atoms
	reset_moleculen(left_side);
	reset_moleculen(right_side);
	
	pside_counter = &left_side;
	
	while(fin >> part)
	{
	
		if(part == "+")
			cout << " + ";
		if(part == "-->")
		{
			cout << " --> ";
			pside_counter = &right_side;
		}
		if(part == "$")
		{
			cout << endl;
			check_reaction(left_side, right_side);
			pside_counter = &left_side;	
		}
		else
		{
			parse_molecule(part, *pside_counter);
			for(i=0; i<DIFF_ATOMS; i++)
				{
					pside_counter++;
				}
		}	
	}
}



/*----------------------------------------------------*/
//Function to reset the valeus.
void reset_moleculen(molecule m)
{
	int i; 
		
	for(i=0; i<DIFF_ATOMS; i++)
	{
		m[i]=0;
	}
}



/*----------------------------------------------------*/
//HERE ARE PROBLEMS!!
//Function for printing the molecules        
//and calculating the numbers of each element
void parse_molecule(string part, molecule m)
{	
	//Values to 0
	//reset_moleculen(m);
	
	int atom_count(0);
	int prefactor, number;
	char letter;
	int i;
	int index;
	
	//Prefactor is standard at 1
	prefactor = 1;
	
	istringstream ins;
	ins.str(part);
	
	if(ins >> number)
		prefactor = number;
	
	if(prefactor>1)
		cout << prefactor << " ";	
	else
		ins.clear();
	
	if(ins >> letter)
		for(i=0; i<DIFF_ATOMS; i++)
		{
			if(letter == atom[i])						
				cout << letter;
		}
		
	else
		ins.clear();
	//for(i=0; i<DIFF_ATOMS; i++)
	//{
	//	while(ins >> letter)								 
	//	{
	//		if(letter == atom[i])						
	//			cout << letter;
	//	}
		
		
	if(ins >> number)
	{	
		if(number>1)
		{
			cout << number;
		}
		else
		ins.clear();
	}
	atom_count++;	
	
        index += prefactor*number;   //Going to be to count the number of elements which helps calculating the mass
	//} 
}



/*----------------------------------------------------*/
//Function to check the reaction and calculate an check the mass
void check_reaction(molecule left_side, molecule right_side)
{
	int i;
	int unequal_counter(0);
	double mass_left(0), mass_right(0);
	
	for(i=0; i<DIFF_ATOMS; i++)
	{
		if(left_side[i] != right_side[i])
		{
			cout << "For atom" << atom[i] << "the number of atoms to the left is: " << left_side[i] << endl;
			cout << "For atom " << atom[i] << "the number of atoms to the right is: " << right_side[i] << endl;
			unequal_counter++;
		}
		//update masses counter
		mass_left += left_side[i] * mass[i];		
		mass_right+= right_side[i] * mass[i];
	}
	cout << "The mass on the left hand side of the equation is: " << mass_left << " u" << endl;
	cout << "The mass on the right hand side of the equation is: " << mass_right << " u" << endl; 
	
	if(mass_left != mass_right)
	{
		cout << "Mass on both side is not the same." << endl;
	}
	
	if(unequal_counter==0)
	{
		cout << "The number of each type of atom is conserved" << endl;
	}
	else
	{
		cout << "The number of each type of atom is NOT conserved" << endl;
	}
	
	cout << endl;
	}

My main problem now is that in the function parse_molecule the equations aren't dispayed properly.

For the input I'm using a file where the reactions have to be implemented in this fashion:
CH4 + 2O2 --> CO2 + 2H2O $

the display has to be in this fashion:
CH4 + 2 O2 --> CO2 + 2 H2O

Using istringstream, I can check every symbol of the string seperately but when I use it now, my output is:
C + 2 O2 --> C + 2H2

so it is working except not all characters are displayed properly. It is probably an error with loops but I can't see where the problem is.

Here is the function again to make it easier to check what's going on:

//HERE ARE PROBLEMS!!
//Function for printing the molecules        
//and calculating the numbers of each element
void parse_molecule(string part, molecule m)
{	
	//Values to 0
	//reset_moleculen(m);
	
	int atom_count(0);
	int prefactor, number;
	char letter;
	int i;
	int index;
	
	//Prefactor is standard at 1
	prefactor = 1;
	
	istringstream ins;
	ins.str(part);
	
	if(ins >> number)
		prefactor = number;
	
	if(prefactor>1)
		cout << prefactor << " ";	
	else
		ins.clear();
	
	if(ins >> letter)
		for(i=0; i<DIFF_ATOMS; i++)
		{
			if(letter == atom[i])						
				cout << letter;
		}
		
	else
		ins.clear();
	//for(i=0; i<DIFF_ATOMS; i++)
	//{
	//	while(ins >> letter)								 
	//	{
	//		if(letter == atom[i])						
	//			cout << letter;
	//	}
		
		
	if(ins >> number)
	{	
		if(number>1)
		{
			cout << number;
		}
		else
		ins.clear();
	}
	atom_count++;	
	
        index += prefactor*number;   //Going to be to count the number of elements which helps calculating the mass
	//} 
}

Another thing is that I have to find a way to actually count how often each element is present on each side of the arrow in the same funtion. I'm thinking about using some sort of index with a for loop..?


Plus I noticed an error in the final function since when a reaction is NOT conserved it still says it is conserved.
But that would be easier to handle once that other function works.


I'll add the data file I'm using for testing as an attachment. In there are three reactions. The first 2 are conserved and are for checking if the display is correct for the reaction and masses. The last one is NOT conserved and should say that.

Any help?

I used this:

while(ins>>letter)
	{
        for(i=0; i<DIFF_ATOMS; i++)
	    {
		
			if(letter == atom[i])						
				cout << letter;}
	
            while(ins >> number)
	        {	
	            if(number>1)
				    cout << number;
		else
	        ins.clear();
	    }
		atom_count++;	
	    index[i] += prefactor*number;
    }

Now when a character comes after another character it prints that, but when there is a number in between them it stops.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.