so im taking the advice of 1ML, seems like a smart guy, and starting a second thread for the controversial, main calling, system calling, devil code, anyway i did take your guys advice and cut out the main calls and reduce everything to one fuction. however! ladies and gentlemen we still have a few problems, among them....

-my arithmetic statments dont return the correct answer(yes i used proper symbols i promise)
-if i cant call main, how do i make it start from the top of main if they type incorrectly?(tried *main(); and &main(); also, if thats considered calling main i will not do it anymore)
-return 0; isn't closing the program without actually showing the stop code? i noticed this after switching from devc++ to code blocks, so maybe thats my issue
-lastly, more of a question, how exactly is iostream and windows.h outdated? aren't those, necessary for: text apps and windows GUI, respectively?


code is as follows

#include<iostream>
#include<windows.h>


using namespace std;
//so this is where i have just the interface, its not really "variables"
//like the one poster mentioned
//also i havent got to class yet...


int main()
{
    //strings that will be used in the program
    string s1;
    string s2;
    double d1;
    double d2;
    double addition = (d1 + d2);
    double subtraction = (d1 - d2);
    double multiplication = (d1 * d2);
    double division = (d1 / d2);
    do
    {
        cout << "What math operation would you like to perform?\n";
        cin  >> s1;


        if((s1=="Division") || s1==("division") || (s1=="/"))
        {
            cout << "Enter the first number: ";
            cin >> d1;
            cout << "Enter the second number: ";
            cin >> d2;
            cout << "The answer is: " << division;   //these work
            cin.ignore();
            cin.get();
        }
        else if((s1=="Addition") || (s1=="addition") || (s1=="+"))
        {
            cout << "Enter the first number: ";
            cin >> d1;
            cout << "Enter the second number: ";
            cin >> d2;
            cout << "The answer is: " << addition;
        }
        else if((s1== "Subtraction") || (s1=="subtraction") || (s1=="-"))
        {
            cout << "Enter the first number: ";
            cin >> d1;
            cout << "Enter the second number: ";
            cin >> d2;
            cout << "The answer is: " << subtraction;
        }
        else if((s1== "Multiplication" || s1=="multiplication") || (s1=="*"))
        {
            cout << "Enter the first number: ";
            cin >> d1;
            cout << "Enter the second number: ";
            cin >> d2;
            cout << "The answer is: " << subtraction;
        }
        else
        {
        cout << "It seems you have mistyped something, try again\n";
        cin.ignore();
        cin.get();
        ?????
        }
    }while((s2=="Y") || (s2=="y"));

    if((s2=="N") || (s2=="n"))
    {
    return 0;
    }
}

Recommended Answers

All 24 Replies

to goto the top of main try a goto statment somethin like

if(variable == 1)
{
	goto a;
}

define a as

a:

then whenever the statment is true it will goto that location

commented: Do not suggest GOTO when there are much better ways -3
commented: That's not good advice at all. -3

by stop code im assuming you mean the press enter to continue?

try

system("pause");

@alex55 where exactly would i put in a? i dont use that variable, and im using cin.get() and cin.ignore() just looking for something to close it, EXIT_SUCCESS works but i still get the 0x00 code, wtf..

You are using your variable declarations like a macro. The reason your result is not coming out correctly is because "division" is set equal to the value of d1 and d2 at the begging of your program, which is just garbage data. Maybe you should use a c macro if you want to do it like that, or an inline function.

@alex55 where exactly would i put in a? i dont use that variable, and im using cin.get() and cin.ignore() just looking for something to close it, EXIT_SUCCESS works but i still get the 0x00 code, wtf..

a does not need to be declared you can put it inside your if or wherever and if the statment runs it will take you to wherever your put

a:

-if i cant call main, how do i make it start from the top of main if they type incorrectly?(tried *main(); and &main(); also, if thats considered calling main i will not do it anymore)

Let's restate the problem... How do you loop back to the beginning of the program?

Try writing a test program to see how you can apply this hint. Get to the point you understand how that works (complete with the YES/NO question).

Then write another test program to try one more single task you need to accomplish. Now merge these two tests.

Continue in this manner.

You're not looping because s2 doesn't equal anything. Don't use goto, you have the right idea with a loop, you just need to fix your execution.
Either:
1. Ask for the input of s2 before ending your loop.
2. Check s1 for a specific input and if it equals that input, end the loop with

break;

thus ending your program.

Also, your second loop is not necessary. Your code will not reach anything after while until you break the loop, that's what a loop does, after all, it repeats the code inside the loop until a condition is met, then it moves down the code.

Finally, your variable functions, as stated earlier, are adding junk. You need to wait until your user inputs the values of d1 and d2 before you assign them to your other variables.

Let's see what you get with that.

Delete lines 71, 72, 74. Worry about valid input later. One thing at a time.

So you want to call main... Well you don't because everyone told you not to, but you want to accomplish what you were trying to accomplish by calling main.

But before trying to REPEAT anything, get it to work the first time.

Line 34 comment: "These work"

Really? That seems impossible or lucky beyond belief or maybe you keep entering the exact same numbers.

But then here you say this:

-my arithmetic statments dont return the correct answer(yes i used proper symbols i promise)

That I believe. Yes you used the proper symbols, but there's another problem, which has been stated earlier. Garbage in, garbage out. You are calculating the result BEFORE you get the two numbers.

Change the program so that it runs correctly the FIRST time through the loop. After you do that, I anticipate that figuring out how to do it again in a loop will become much easier.

I think you've misunderstood how to make functions. The statements at the top of your code like this:

double addition = (d1 + d2);
double subtraction = (d1 - d2);
double multiplication = (d1 * d2);
double division = (d1 / d2);

don't do what I think that you think they do. All they do is set the value of, say, subtraction to what ever the value of d1 - d2 is, at that exact moment, which in your case is unknown since you don't initialise them to any value. Later, when you do, say:

cout << "Enter the first number: ";
cin >> d1;
cout << "Enter the second number: ";
cin >> d2;
cout << "The answer is: " << addition;

you're reading in d1 and d2 but the statement cout << "The answer is: " << addition; just prints the previously assigned (jibberish) value of addition , it doesn't do what you want, which is to re-calculate the value as d1 - d2 .

You need to make functions that perform this task. I recently made another post about making functions for a very similar application, here. I think that post should give you more idea about what functions do and how to make ones such as multiply(double, double) etc.

ooh sorry about the comment "this works" that was for a kid i sent this to so he could look it over, many a revision ago, ill recomment.....and okay cool i get the part where i should declare the functions after getting input i guess i was just to putting up everything that was going to be used there at the top, but sounds good ill fix that, and why do you guys keep telling me to loop for the error code, even if i do a loop with a break it wont let the user "try again" which was the whole goal of this program, to make something functional, like i use at work, if you type something wrong it keeps clearing and letting you try again. but while somebody helps on that, im gonna fix this code a bit

commented: you shouldn't send friends code +0

also, just finished this code to exactly how i wanted it to work, and to the contrary, of a previous statement here, calling main didnt increase the memory in usage, and heres my logic as to why.... like my book says "the compiler is pretty good about getting down your code into the fewest machine code instructions possible" and that must be true because i started spelling things wrong over and over and the memory usage actually went down a bit, even with doing huge number multiplication, anyway could you guys offer a better solution to exiting the console without the "return 0;" because i dont need an error code i need something that looks professional.

#include<iostream>
#include<windows.h>

using namespace std;

int main()
{
    string s1;
    string s2;
    double d1;
    double d2;//fixed
    do
    {
        cout << "What math operation would you like to perform?\n";
        cin  >> s1;


        if((s1=="Division") || s1==("division") || (s1=="/"))//still need a way to return to main
        {                                                    //without calling main
            cout << "Enter the first number: ";
            cin >> d1;
            cout << "Enter the second number: ";
            cin >> d2;
            double division = (d1 / d2);
            cout << "The answer is: " << division;
            cout << endl;
            cout << "Would you like to perform another operation?\n";
            cin >> s2;
            system("CLS");
        }
        else if((s1=="Addition") || (s1=="addition") || (s1=="+"))
        {
            cout << "Enter the first number: ";
            cin >> d1;
            cout << "Enter the second number: ";
            cin >> d2;
            double addition = (d1 + d2);
            cout << "The answer is: " << addition;
            cout << endl;
            cout << "Would you like to perform another operation?\n";
            cin >> s2;
            system("CLS");
        }
        else if((s1== "Subtraction") || (s1=="subtraction") || (s1=="-"))
        {
            cout << "Enter the first number: ";
            cin >> d1;
            cout << "Enter the second number: ";
            cin >> d2;
            double subtraction = (d1 - d2);
            cout << "The answer is: " << subtraction;
            cout << endl;
            cout << "Would you like to perform another operation?\n";
            cin >> s2;
            system("CLS");
        }
        else if((s1== "Multiplication" || s1=="multiplication") || (s1=="*"))
        {
            cout << "Enter the first number: ";
            cin >> d1;
            cout << "Enter the second number: ";
            cin >> d2;
            double multiplication = (d1 * d2);
            cout << "The answer is: " << multiplication;
            cout << endl;
            cout << "Would you like to perform another operation?\n";
            cin >> s2;
            system("CLS");
        }
        else
        {
        cout << "It seems you have mistyped something, try again\n";
        cout << "Press Any Key To Continue..";
        cin.ignore();
        cin.get();
        system("CLS");
        main();//this will be here untill i get a solution, im sorry, truely
        }
    }while((s2=="Y") || (s2=="y"));

    if((s2=="N") || (s2=="n"))
    {
    return EXIT_SUCCESS;
    }
}

Error codes look professional. Otherwise, you can use void main(). Usually you use int main() and return 0. No one will penalize your code for doing so.

Besides, you're not going to see the overhead in a small program like this. The point of talking you out of doing it is so later on it doesn't cause a problem. A lot of the programming taboos will work fine in small codes but will destroy a large one, which is why it's customary to learn to code properly from the beginning.

Try deleting your Main function call, and, like I suggested earlier, get rid of the if check before the return. Then, run your program and hit "Y" when it asks you if you want to try again, just as you specified. See if it works.

commented: No, you NEVER use void main(). Search these forums to see why, -3

OK, one last time and then I'm done with this!

also, just finished this code to exactly how i wanted it to work, and to the contrary, of a previous statement here, calling main didnt increase the memory in usage, and heres my logic as to why.... like my book says "the compiler is pretty good about getting down your code into the fewest machine code instructions possible" and that must be true because i started spelling things wrong over and over and the memory usage actually went down a bit, even with doing huge number multiplication

You probably can't run through the program enough times doing this manually to make a difference, since your program is quite small and the stack is quite big. If you want to see this bug in action try running this code:

#include <iostream>

int main(){
    double a = 0;
    std::cout << a;

    return main();
}

It will run for a bit and then produce a segmentation fault. Count the number of zeros to see how many copies of main() it generated.

Compiler optimisation is irrelevant here, memory is being wasted so eventually it will run out and everything will crash. Your test of running your code a few times and looking at the memory usage is not really a good one, since the stack (where programs exist) is very much smaller than the total memory on the computer (most of which is the stuff that you can access by using new to dynamically allocate memory).

That's all I have to say on the subject. Run the code about and you will see the problems with calling main() in your code. The other problem is that you will never get a job in software development or be taken seriously by other programmers until you stop doing this!

anyway could you guys offer a better solution to exiting the console without the "return 0;" because i dont need an error code i need something that looks professional.

No. Returning 0 is the professional thing to do if your program exits successfully. The EXIT_SUCCESS variable that you've used in your code is probably just defined as zero somewhere. In any case, if you want to look professional: don't call main() !

There's zero overhead to your program involved in returning a value at the end of execution. By definition, your program has already done the things that the user is interested in before it gets to the return part. Don't use void main() , it should cause an error (or at least a warning) on most compilers anyway. If you do use void main() and your program compiles and runs, then you can potentially cause problems in other programs. For example, if another program calls yours and is waiting for a return value from it (to check if everything was OK or not) then undefined behaviour might occur.

And finally... Your code currently has this on line 77:

main();//this will be here untill i get a solution, im sorry, truely

The solution to this problem is to replace it with:

s2 = "Y";

That's it. That's the whole thing that you had to figure out to make all these problems and misery of calling main() go away. So there you go. No further need to call main() . Done.

commented: Good effort in this horror-thread +16
commented: Very nice, succinct, high quality post. +13
commented: You cant make it much more clear than that i'm sure +3
#include <iostream>

int main(){
    double a = 0;
    std::cout << a;

    return main();
}

It will run for a bit and then produce a segmentation fault. Count the number of zeros to see how many copies of main() it generated.

Great example.

And finally... Your code currently has this on line 77:

main();//this will be here untill i get a solution, im sorry, truely

The solution to this problem is to replace it with:

s2 = "Y";

That's it. That's the whole thing that you had to figure out to make all these problems and misery of calling main() go away. So there you go. No further need to call main() . Done.

Yup. Can't get much easier than that.

sorry for that but i don't think he learn that way,he just try to find out the wrong things without understand why they are wrong...wont be more usefull for him to name the things that he has to go and read about?

that s2="y"; is so brilliant thank you, see thats the kinda thinking i need to get into and im glad you guys have sparked up my thought, again im new to this and being able to dynamically change the value of s2 and thinking how the code changes from code to binary its all a little confusing but i get it, and the code works fine now, and doesnt ever call main(); woohoo, so now i guess for the headers? im really interested on that topoic

Just a quick question:
What's the variable that you are returning?

You should probably close this thread since you got a solution.

Bad code was her, deleted it, sorry...

Sorry, was going to post some code here, but I have to do some stuff with my son, suffice it to say you should probably be using a switch statement rather than a load if then else which gets confusing to read. I'll post the code latter on. Sorry again...

Disregard the code fragment that got posted by accident, not really used to the interface on this thing, but I do have a working solution for you when I get a chance, which will hopefully be later on this evening :)

1ML

OK, deleted the code that was there because it would probably have been more confusing than useful. I'll write up a full program latter on, I've got top go do stuff with my son.

See ya :)

commented: You can edit your posts up to 30 minutes afterwards, no need to bombard the thread. -1

First you need to fully understand why it's a bad thing to call main. When the system calls main it also calls code created by the compiler that
sets up the heap and the stack for static and dynamically created variables so that no other program can use that memory. Calling main a second
time from within the first main causes that entry code to be re-executed and for a second stack and heap to be created.
When the second main is exited a cleanup routine tells the OS to release exclusive rights over the memory allocated for heap as
though the program was ending, and the heap and stack of that program is released back to the OS.
That means that any program including the OS can, and probably will, use that memory and the variables that you created within the context
of the second main are now outside the scope of the original program setup by the first main.
Also their value is garbage as any process can and probably will be overwrite by another program .
Ergo you can't really on those values, plus your potentially trying to access pointers outside the context of the program.

Program pseudocode, the rest you should be able to do your self :)

This isn't about solving your maths problems, but if you actually do it like this you find that solving problems becomes easier

/* First off anything you can test with == you can put into a switch statement which
   is easier to read and to debug.
   
   Secondly you need to use encapsulation to make your code easier to both read
   and maintain. 

   If you get into the habit of doing this in simple programs you'll use it
   naturally in complex one's.
 
   Also you create reusable objects 
*/


/* 
In this instance cUserMathObject a complex object that encapsulates the
   behaviour required from an object that needs to add, subtract, multiply, and
   divide two values. 
   Also it test that that the input is correct, and parsing all the values. We 
   assume that this is the start of main() and that cUserMathObj is defined 
   elsewhere and in include is provided. We also assume that all return values are
   static string objects
*/
        
        
// the c on cInput tells anyone reading the code that it's a class 
// you'll find various standards for this, really the only thing that's important
// is that it's rational and you stick to it. i.e. don't mix and mingle

cUserMathObj cInput  = ""; 


// Each time the loop goes round the GetUserImput gets the input then
// test it to make sure that it's valid. While doing this it parses the components 
// to actually do the maths with and puts them into private class variables that are 
// accessed by public functions

while( cInput.GetUserInput())
{
    // Print out a text string of the expression for the user
    out << cInput.GetExpression();
    
    
    // This alows us to seperate out the verious operators, though to make the 
    // object actually usefull you should put all of this into the object it's self
    // and simply have it perform thius functionality. Also you should be using
    // throw and catch statements to perform exception handling rather than error
    // handling wich is way more C tha C++
    // But for the purpouses of this example it's easier to describe the behaviour 
    // this way

    switch( cInput.GetOpperator() )
    {
        // Use code once unless you absolutely have to repeat your self
        // that way if it needs to be cahnged you only need to change it once
        // in one place.

        out << "Your answer anser is: "

        /* Now the actual case statemnts that switch between values
           within each case stement the encapuslated code is called 
           for each unumerated value that GetUserInput seperates out 
           into an;
            1. a enum typedef for the operator
            2. the values the operator that are heald in an object private variable
            3. A return value of truy or fals depending on weather the input is
               apropriate for the program 
        */
            
        case uAdd :
            out << cInput.GetAddedValues();
            break;

        case uDev :
            out << cInput.GetDevideValues();
            break;

        case uSub :
            out << cInput.GetSubedValues();
            break;

        case uMul :
            out << cInput.GetMuledValues();
            break;
            
        case uImposible:
            // Print out an error message that the expression is an imposible
            // i.e. devide by 0
            out << cImput.ImposibleExpession();
            break;
            
        case uExit :
            out << "Exiting program"
            break;

       default:
            // UNKONW_ERROR_CODE would be defined as a #define macro i.e. 
            // #define UNKONW_ERROR_CODE -1
            out << "Unknown error"
            exit( UNKNOWN_ERROR_CODE );
           break;

    } // end swicth document this because it's then easier to find in a complex nest
} // end while, same as before. Do it for simple core and it becomes a habit

// Similarly #define GOOD_EXIT 0
exit( GOOD_EXIT );


// the rest you should be able to write your self
// For top props encapsulate the the whole thing as an object that has to be
// called once and examine how modulare each object is, i.e that it defines and
// performs a specific task don't forget inheritance...

Like I said at the star I've not programed in anger for a while, so I admit that their may be some syntactic error, but the general principles remain sound

Oh, and I haven't compiled any of this, it's all off the top of my head, so don't expect too much dude, but the point I'm trying to make is that your problems are being compounded by unstructured code, basically your writing C, you should be putting all of that stuff into object so you can just change the object and it's updated anywhere the object is used when you recompile

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.