Page 1 of 1

Rebuilding expr

Posted: Sat 14 Aug 2010, 17:02
by thelaptopkiller
I'm working on learning C++.
As my first real test I wanted to build a better expr.
But it doesn't seem to do any adding or print the answer.

Here is the code:

Code: Select all

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char* argv[])
{

  int proarg;
  float fltAnswer;
  if ( argc != 4 )
    cout << "Usage: expr number1 +-/* number2";
  else

     float arg1 = atof(argv[2]);
     float arg2 = atof(argv[4]);
     if (argv[3] == "/")
     proarg = 1;
     else if (argv[3] == "*")
     proarg = 2;
     else if (argv[3] == "+")
     proarg = 3;
     else if (argv[3] == "-")
     proarg = 4;

	 switch (proarg)
     {
        case 1 :
            fltAnswer = (float) arg1 / arg2;
            cout << fltAnswer;
            break;
        case 2 :
            fltAnswer = (float) arg1 * arg1;
            cout << fltAnswer;
            break;
        case 3 :
            fltAnswer = (float) arg1 + arg2;
            cout << fltAnswer;
            break;
        case 4 :
            fltAnswer = (float) arg1 - arg1;
            cout << arg1 << "+" << arg2 << fltAnswer;
            break;
        }
}
I'm building it with Code::Blocks ver. 8.2

Help anyone?

Posted: Sun 15 Aug 2010, 14:55
by muggins
Hello thelaptopkiller,

I'm nearly there. I altered your code to:

Code: Select all

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char* argv[])
{
	
  float fltAnswer;
  float arg1 = atof(argv[1]);
  float arg3 = atof(argv[3]);
  
	if ( argc != 4 )
	{	
	  cout << "Usage: expr number1 +-/* number2";
	  exit(1);
	}
   

    switch (argv[2][0])
    {
        case '/' :
            fltAnswer = (float) arg1 / arg3;
            cout << fltAnswer;
            break;
        case '*' :
            fltAnswer = (float) arg1 * arg3;
            cout << fltAnswer;
            break;
        case '+' :
            fltAnswer = (float) arg1 + arg3;
            cout << fltAnswer;
            break;
        case '-' :
            fltAnswer = (float) arg1 - arg3;
            cout << arg1 << "+" << arg3 << fltAnswer;
            break;
     
	}
     return 0;
} 
The only thing not working is that it is that, for some reason, "6 * 4" is being seen as argc==4.

Two things regarding argv. If you call the program arithmetic, then run:

Code: Select all

./arithmetic 2 + 3
argv[0] = ./arithmetic
argv[1] = 2
argv[2] = +
argv[3] = 3

And in parsing argv[2], for the switch statement, it is actually like an array, and the "+" is contained in the first element of this array, [2][0].

I'll see if I can work out why the "*" isn't working...unless someone else comes along with a solution.

Edit: The switch should be for [2][0].

Posted: Sun 15 Aug 2010, 15:18
by muggins
If you replace "*" with "x", as the multiplier operator, then the above code works with multiply. I wonder whether using * is seen as a pointer?

Posted: Sun 15 Aug 2010, 15:24
by rcrsn51
Or maybe the * is being processed as a wild-card operator.

Posted: Sun 15 Aug 2010, 19:54
by thelaptopkiller
I tried the new code and the program crashed.
You see as puppy linux dislikes my wifi card I'm stuck with good(much better then win 7) old win XP.
So when I run it window$ screams ERROR! ERROR! in my face.
Now I'm stuck with finding a way to make it window$ friendly.

Heres my new code:

Code: Select all

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char* argv[])
{
  float arg1 = atof(argv[2]),arg2 = atof(argv[4]),fltAnswer;

  if ( argc != 4 )
 {
    cout << "Usage: expr number1 +-/x number2";
    exit(1);
 }
  else
{

    switch (argv[2][0])
    {
        case '/' :
            fltAnswer = (float) arg1 / arg2;
            cout << fltAnswer;
            break;
        case 'x' :
            fltAnswer = (float) arg1 * arg2;
            cout << fltAnswer;
            break;
        case '+' :
            fltAnswer = (float) arg1 + arg2;
            cout << fltAnswer;
            break;
        case '-' :
            fltAnswer = (float) arg1 - arg2;
            cout  << fltAnswer;
            break;

   }
}
}

Posted: Sun 15 Aug 2010, 22:26
by Patriot
Hmmm .....

The '*' is a bash special character. Need to escape it :

# expr 3 \* 5


Rgds

Posted: Mon 16 Aug 2010, 00:12
by muggins
Thanks Patriot, that works, but for simplicity probably better to just use "x".

laptopkiller, have a look at your code, for handling arguments, again. Just as with Grub bootloader, where the first disk is (hd0,0) not (hd0,1), similarly when argv processes ./progname 6 / 7, the 6 is argv[1], / is argv[2] & 7 is argv[3].