How to make my program shorter using arrays or other method?

Hello Everyone
This is just part of my code, this small program converts units from one to another (for example: tons to kilograms and vice-versa). Since I included different types of conversion like temperature, currency, size, etc using this same method below... my program has grown up to 3500 lines, and I am sure there is a way to make it smaller, I read about arrays I understand the basic of it and how to program basic examples with it but I do not know how to include arrays in my program to make it shorter, and if there is any other way I would love to hear from it, I have been stuck for a while already also because I did not have enough time to program but I will really appreciate if somebody can help me how to continue improving my coding, thanks in advance.

The program runs perfectly fine like I wanted, its just the size that bugs me, the efficiency and maintainability of the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  double startMU()
{
	char answerExit = 'y';
	string unit1;
	string unit2;
	double amount;
		
	const double tn_kg = 1000;   const double tn_lb = 2204.62;     const double tn_oz = 35274;     const double lb_oz = 162;
	const double kg_tn = 0.001;  const double lb_tn = 0.000453592; const double oz_tn = 2.835e-5;  const double oz_lb = 0.06252;
	const double kg_g = 1000;    const double kg_lb = 2.20462;     const double kg_oz = 35.274;
	const double g_kg = 0.001;   const double lb_kg = 0.453592;    const double oz_kg = 0.0283495;
	const double tn_g = 1e+6;    const double g_lb = 0.00220462;   const double g_oz = 0.035274;
	const double g_tn = 1e-6;    const double lb_g = 453.592;      const double oz_g = 28.3495;

	const double tn_tn = 1; const double lb_lb = 1;
	const double kg_kg = 1; const double oz_oz = 1;//25
	const double g_g = 1;
	
	printMUmenu();

LOOP_massUnits:
	do {
			cout << "\n Insert unit to convert: ";
			cin >> unit1;
			cout << " Insert unit to obtain: ";
			cin >> unit2;
			if (unit1 == "tn" && unit2 == "kg")
			{
				cout << "\n How many " << unit1.c_str() << " do you want to convert? ";
				cin >> amount;
				cleanCin();
				cout << " " << amount << " " << unit1.c_str() << " are " << amount * tn_kg << " " << unit2.c_str() << ".\n";
			}
			else if (unit1 == "kg" && unit2 == "tn")
			{
				cout << "\n How many " << unit1.c_str() << " do you want to convert? ";
				cin >> amount;
				cleanCin();
				cout << " " << amount << " " << unit1.c_str() << " are " << amount * kg_tn << " " << unit2.c_str() << ".\n";
			}

			/*...and so on with 26 possible combinations in total...*/

			else if (unit1 != "tn", "kg", "g", "lb", "oz" && unit2 != "tn", "kg", "g", "lb", "oz")
			{
				cout << "\nERROR: Invalid Unit\n";
				goto LOOP_massUnits;
			}
	} while (answerExit != 'y');
	return 0;
}
A few comments:

Line 47: Get rid of the goto. Gotos should be avoided. They result in spaghetti code. You already have a loop. Use a continue statement to go to the top of the loop.

Lines 29: There is no reason to take a c_str() of a string. You can use a string (unit1) directly in a cout statement.

Line 44: Your if statement is faulty. You can not have implied left side of a comparison. Each comparison must be fully specified.
 
else if (unit1 != "tn" && unit1 != "kg" && unit1 != "g" && unit1 != "lb" && unit1 != "oz" ... etc ) 


I would suggest using a std::map.
1
2
3
 
  std::map<string, double>  factors {"kg_tn", 0.001, "tn_kg", 1000, ... }
  // Initialization syntax requires C++11 

Now all you have to do is build a key which is the concatenation of the from and to units.
1
2
  string key;
  key = unit1 + '_' + unit2;

Then look that up in the map.
1
2
3
4
5
6
7
8
9
10
11
 
  std::map<string,double>::const_iterator citer;
  double factor;

  citer = factors.find (key);
  if (citer == factors.end()
  {   //  not found  }
  else
  {  factor = citer->second;
      // cout conversion message
  }

All your if/else statements go away.
Last edited on
Look at the description of std::map at the Reference section.

Lets make a simpler table:
tn 1e+6
kg 1000.0
lb  453.6
oz   28.4
 g    1.0

You do get input amount and unit.

You can look up the unit from the table. If the input is not in the table, then it is invalid. Use a while-loop to get valid input. Do not use goto. While 'goto' may appear "simple", it actually makes program more complex and error-prone.

Now you have a valid unit. The table has a corresponding value. If you do multiply the amount with the value, you do perform a conversion to what unit?

Then you have the output unit and its corresponding value. If you divide the result of previous multiplication with the output-value, you again convert the unit. From what to what?

It is an extra optimization to handle the input==output non-conversions.


Why do you print the std::strings as C-strings?
Topic archived. No new replies allowed.