Rebuilding expr

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Post Reply
Message
Author
thelaptopkiller
Posts: 66
Joined: Sun 25 Oct 2009, 14:23
Location: The only place in tornado ally with no tornadoes

Rebuilding expr

#1 Post 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?
[img]http://www.robotech.com/images/content/MEC_17_1_6899.gif[/img]
[b]Really,you wanna mess with me?[/b]

muggins
Posts: 6724
Joined: Fri 20 Jan 2006, 10:44
Location: hobart

#2 Post 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].

muggins
Posts: 6724
Joined: Fri 20 Jan 2006, 10:44
Location: hobart

#3 Post 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?

User avatar
rcrsn51
Posts: 13096
Joined: Tue 05 Sep 2006, 13:50
Location: Stratford, Ontario

#4 Post by rcrsn51 »

Or maybe the * is being processed as a wild-card operator.

thelaptopkiller
Posts: 66
Joined: Sun 25 Oct 2009, 14:23
Location: The only place in tornado ally with no tornadoes

#5 Post 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;

   }
}
}
[img]http://www.robotech.com/images/content/MEC_17_1_6899.gif[/img]
[b]Really,you wanna mess with me?[/b]

User avatar
Patriot
Posts: 733
Joined: Thu 15 Jan 2009, 19:04

#6 Post by Patriot »

Hmmm .....

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

# expr 3 \* 5


Rgds

muggins
Posts: 6724
Joined: Fri 20 Jan 2006, 10:44
Location: hobart

#7 Post 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].

Post Reply