### Thread: C++ simple calculator.

Page 1 of 2 12 Last
1. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2006
Posts
45
Rep Power
16

#### C++ simple calculator.

I started learning about objects and decided to write a simple calculator program.

Here are the files for it:

c++ Code:
```class Calculator
{
private:
float a;
float b;
public:
Calculator(); //constructor
float subtract(float, float);
float divide(float, float);
float multiply(float, float);
};

#include "c:\myCalculator.cpp"```

implementation:
c++ Code:
```Calculator::Calculator()
{
a = 0;
b = 0;
}

float Calculator::add(float a, float b)
{
return a + b;
}

float Calculator:: subtract(float a, float b)
{
return a - b;
}

float Calculator::divide(float a, float b)
{
return a / b;
}

float Calculator::multiply(float a, float b)
{
return a * b;
}```

main:
c++ Code:
```#include<iostream>
#include "c:\myCalculator.h"

using namespace std;

void main()
{
Calculator calc;

int x, y;
char input;
string func;

cout<<"You can choose from add, subtract, divide or multiply."<<endl;
cout<<"Do you have 2 numbers to perform a function on? (y/n)";
cin>>input;

while(input != 'n')
{
cout<<"What function would you like to try? ";
cin>>func;

{
cout<<"Type in 2 numbers to add: ";
cin>>x>>y;
cout<<x<<" + "<<y<<" = "<<calc.add(x,y)<<endl;
}

else
{
if(func == "subtract")
{
cout<<"Tpye in the bigger number first and then the second number: ";
cin>>x>>y;
cout<<x<<" - "<<y<<" = "<<calc.subtract(x,y)<<endl;
}

else
{
if(func == "divide")
{
cout<<"Enter the divisor followed by the dividend: ";
cin>>x>>y;
cout<<x<<" ÷ "<<y<<" = "<<calc.divide(x,y)<<endl; // ÷ alt 246; 0247
}

else
{
if(func == "multiply")
{
cout<<"Enter the two numbers to multiply: ";
cin>>x>>y;
cout<<x<<" x "<<y<<" = "<<calc.multiply(x,y)<<endl;
}

else
cout<<"You didn't enter one of the supported functions."<<endl;
}
}
}

cout<<"Try again? ";
cin>>input;
}
}```

This is the error I got (4 times):
error C2676: binary '==' : 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' does not define this operator or a conversion to a type acceptable to the predefined operator

and this error once: error C2679: binary '>>' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or there is no acceptable conversion)

It's probably something obvious but I can't remember what I'm doing wrong.
2. I don't see "include <string>" there anywhere. Further, including a .cpp file in a .h file is dangerous practice.

Not checking the success of your input operations is also dangerous practice. I can break your program with a couple of keystrokes.

I would also suggest, from a UI point of view, that a calculator asking if it wants to be used, immediately after being turned on, is somewhat silly. I might also suggest the use of "+", "-", "*", and "/".
3. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2006
Posts
45
Rep Power
16
>.< I forgot to include <string>.

Why is including a .cpp file in an .h file bad?

What do you mean "I might also suggest the use of "+", "-", "*", and "/"." I used those in the functions? Where do you suggest I use those?

Lastly, I didn't think about the calculator asking whether it wants to be used after it's on. That is pretty silly now that you mention it. I'll remove that.
4. I believe he means instead of having the user input "subtract" why not have the user input "/" instead? It's easier and simpler for the user.

Typically you want to include header files (".h" files) in your source files (".cpp"), not the other way around. Including .cpp files can often lead to multiple definition compiler errors or linker errors as code gets pasted into the same file multiple times, or duplicate code gets pasted into separate source files.
5. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2006
Posts
45
Rep Power
16
Originally Posted by ComputerPhreak
I believe he means instead of having the user input "subtract" why not have the user input "/" instead? It's easier and simpler for the user.

Typically you want to include header files (".h" files) in your source files (".cpp"), not the other way around. Including .cpp files can often lead to multiple definition compiler errors or linker errors as code gets pasted into the same file multiple times, or duplicate code gets pasted into separate source files.
I changed the words to symbols.
c++ Code:
```#include<iostream>
#include<string>
#include "c:\myCalculator.h"

using namespace std;

void main()
{
Calculator calc;

float x, y;
char input;
char func;

cout<<"You can choose from +, -, /, or x."<<endl;
cout<<"Do you have 2 numbers to perform a function on? (y/n) ";
cin>>input;

while(input != 'n')
{
cout<<"What function would you like to try? ";
cin>>func;

if(func != ('+' || '-' || '/' || 'x'))
{
if(func == '+')
{
cout<<"Type in 2 numbers to add: ";
cin>>x>>y;
cout<<x<<" + "<<y<<" = "<<calc.add(x,y)<<endl;
}

else
{
if(func == '-')
{
cout<<"Type in the number to subtract from followed by the number you're subtracting: ";
cin>>x>>y;
cout<<x<<" - "<<y<<" = "<<calc.subtract(x,y)<<endl;
}

else
{
if(func == '/')
{
cout<<"Enter the divisor followed by the dividend: ";
cin>>x>>y;
cout<<x<<" ÷ "<<y<<" = "<<calc.divide(x,y)<<endl; // ÷ alt 246; 0247
}

else
{
if(func == 'x')
{
cout<<"Enter the two numbers to multiply: ";
cin>>x>>y;
cout<<x<<" x "<<y<<" = "<<calc.multiply(x,y)<<endl;
}

else
cout<<"You didn't enter one of the supported functions."<<endl;
}
}
}
}

else
{
cout<<"You didn't choose a supported function. Try again: "<<endl;
cin>>func;
}

cout<<"Try again? ";
cin>>input;
}
}```

Got it. Thanks guys!

One question: is it possible to write the program asking the user to enter a function (like having the user enter 3 + 5) and recognizing that the user wants to add and giving the answer? I don't know how that's done.
6. Let me expand on what ComputerPhreak says. ".h" files are copied intact to the .c or .cpp files. It's precisely like a copy or paste. They are part of the .cpp or .c files before compilation is attempted. (It's a part of the preprocessing that takes place before compilation, in precisely the same way that #defines and other #whatever statements are processed).

Header files (.h) are essentially useless unless they can apply to multiple source files. If they can apply to multiple source files, good. If they only apply to one file, just add them there.

If they actually define things, then they will lead to multiple definitions when used across multiple source files. They should normally only specify declarations.

If you're going to only use a header file once, you might as well just put it in the source file, because that's what the preprocessor is going to do.

I would suggest that you learn about the build process. It involves preprocessing, compilation, linking, and possibly (less often encountered in easy program generation) locating.

You can write programs from now until you retire without understanding what's going on, but under those circumstances you will never be a programmer who is more than merely adequate.

That's just a fact, like it or not. No offense intended, though I might roll my eyes.
7. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2006
Posts
45
Rep Power
16
Just to make sure, you mean I should paste:

Code:
```class Calculator
{
private:
float a;
float b;
public:
Calculator(); //constructor
float subtract(float, float);
float divide(float, float);
float multiply(float, float);
};

#include "c:\myCalculator.cpp"```
in main.cpp under <iostream> and instead of "myCalculator.h"? Like so:

c++ Code:
```#include<iostream>

class Calculator
{
private:
float a;
float b;
public:
Calculator(); //constructor
float subtract(float, float);
float divide(float, float);
float multiply(float, float);
};
#include "c:\myCalculator.cpp"

using namespace std;

void main()
{
Calculator calc;

float x, y;
char input;
char func;

cout<<"You can choose from +, -, /, or x."<<endl;
cout<<"Do you have 2 numbers to perform a function on? (y/n) ";
cin>>input;

while(input != 'n')
{
cout<<"What function would you like to try? ";
cin>>func;

if(func != ('+' || '-' || '/' || 'x'))
{
if(func == '+')
{
cout<<"Type in 2 numbers to add: ";
cin>>x>>y;
cout<<x<<" + "<<y<<" = "<<calc.add(x,y)<<endl;
}

else
{
if(func == '-')
{
cout<<"Type in the number to subtract from followed by the number you're subtracting: ";
cin>>x>>y;
cout<<x<<" - "<<y<<" = "<<calc.subtract(x,y)<<endl;
}

else
{
if(func == '/')
{
cout<<"Enter the divisor followed by the dividend: ";
cin>>x>>y;
cout<<x<<" ÷ "<<y<<" = "<<calc.divide(x,y)<<endl; // ÷ alt 246; 0247
}

else
{
if(func == 'x')
{
cout<<"Enter the two numbers to multiply: ";
cin>>x>>y;
cout<<x<<" x "<<y<<" = "<<calc.multiply(x,y)<<endl;
}

else
cout<<"You didn't enter one of the supported functions."<<endl;
}
}
}
}

else
{
cout<<"You didn't choose a supported function. Try again: "<<endl;
cin>>func;
}

cout<<"Try again? ";
cin>>input;
}
}```

Should I include the functions in main.cpp too?

Also, is it possible to write the program asking the user to enter a function (like having the user enter 3 + 5) and recognizing that the user wants to add and giving the answer? I don't know how that's done.
8. Anytime you see a statement that says '#include <whatever.cpp>' or '#include "whatever.cpp"', you are already asking for trouble. It might very well not bite you until you have to write a program that is somewhat more complicated than "Hello, World."

I gave the reasons above, but unless you stop and think about them, and understand the process, you won't know until they have sneaked up on you and enlarged your asshole a time or two.
9. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2006
Posts
45
Rep Power
16
Thanks for the tips. I put all the stuff in main.cpp. The reason I was doing it the other way was because that's how my teacher said it's done when people write programs. He didn't explain that there could be any issues.

Also, is it possible to write the program asking the user to enter a function (like having the user enter 3 + 5) and recognizing that the user wants to add and giving the answer? I don't know how that's done.
10. Copy and paste the pertinent parts of this page and print them out. Then inform your teacher what experienced programmers have told you that your teacher doesn't know what he's talking about and that he is seriously misleading his students (only be more diplomatic about it if you'd prefer).

In order to write a multiple-file project (one with more than one .cpp file) is to associate them to the project. Traditionally, this is done with a makefile and the make utility. More commonly on Windows and DOS systems is to use an integrated development environment (IDE) such as Microsoft Visual Studio, Borland C++, Turbo C++, Dev-C++, etc. In the typical IDE, there's a Project item in the main menu which provides options to create a new project and to add files to that project. Adding a source file to a project will cause it to be included in that project's build.

As explained, in a multiple file project you would declare header files to contain datatypes, classes, structs, macros (#define's), function prototypes, and variable extern's (an extern statement that describes a variable, but does not create it; that variable then needs to be created in one and only one source file). Then every source file that needs anything that a header file contains will include that header file.

The only exceptions I can think of for including code in a header file are:
1. inline functions and methods.
2. templates.

BTW, one problem we've seen created by your teacher's practice is when a newbie has written parts of a larger program as smaller programs and then tries to include them all into one file. Yep, that's right, he got multiple instances of main and had to come here to learn why that was wrong.
11. Originally Posted by bdawg923
Also, is it possible to write the program asking the user to enter a function (like having the user enter 3 + 5) and recognizing that the user wants to add and giving the answer? I don't know how that's done.
You would need to parse the line to separate out the operands and the operator. That is of course a more complicated task.

If you feel adventurous, Google on "Shunting algorithm" and postfix notation. The shunting algorithm converts an infix string (eg, 3+5) into a postfix string (eg, 3 5 +) which is then ideal for evaluating with a stack. But we covered that in an upper-division college course and, judging by your teacher's expertise, you're in high school.
12. Originally Posted by bdawg923
Thanks for the tips. I put all the stuff in main.cpp. The reason I was doing it the other way was because that's how my teacher said it's done when people write programs. He didn't explain that there could be any issues.

Also, is it possible to write the program asking the user to enter a function (like having the user enter 3 + 5) and recognizing that the user wants to add and giving the answer? I don't know how that's done.
The point isn't to stuff everything in main.cpp. What we're saying is not to (almost) ever #include .cpp files. Here is how you should structure your program:

Code:
```class Calculator
{
private:
float a;
float b;
public:
Calculator(); //constructor
float subtract(float, float);
float divide(float, float);
float multiply(float, float);
};```
That is what defines the interface to your class. You want this to be available to any compilation unit that needs to instantiate (create an instance of) your class. Accordingly, you should put this in a .h file, probably named "calculator.h" or whatever you prefer.

Now, you need to include this file in your "calculator.cpp" file, because you are using the 'calculator' class interface (located in your header file, "calculator.h") in implementing the actual code for the class (located in your source file "calculator.cpp"). The top of "calculator.cpp" ought to resemble the following:

Code:
```#include "calculator.h"

... (the rest of your code)```
In your "main.cpp" file you have two external requirements: the stuff in <iostream> required to read/write to the console, and the definition of your class 'calculator'. So you'd include two header files:

Code:
```#include <iostream>
#include "calculator.h"

....```
13. Originally Posted by dwise1_aol
You would need to parse the line to separate out the operands and the operator. That is of course a more complicated task.

If you feel adventurous, Google on "Shunting algorithm" and postfix notation. The shunting algorithm converts an infix string (eg, 3+5) into a postfix string (eg, 3 5 +) which is then ideal for evaluating with a stack. But we covered that in an upper-division college course and, judging by your teacher's expertise, you're in high school.
I think you'd only need to implement that algorithm if you want to handle order of operations properly. But I can think of a much simpler way to do things if you assume input is of the following grammar:
operand1 operation operand2

Code:
```...

float op1, op2;
char operation;

std::cin >> op1 >> operation >> op2;

switch(operation)
{
case '+':
...
case '-':
...
case '/':
...
case '*':
...
default:
}
...```
14. To be fair, it sounds as if the OP was only following orders the instructor's lead in regards to the design of the program. GIGO.

I am assuming - hoping, actually, though it's a bit of a forlorn hope given some supposed experts I've seen teaching this subject - that the teacher did in fact explain it correctly, just not clearly. What ComputerPhreak and the others have said about SOP is pretty much on the money, but reading this without knowing what they meant would probably be confusing.

Here's the scoop, or at least my side of it:

A big part of programming, especially in an object-oriented language like C++, is being able to use the same functions or objects in many different programs, so that you don't have to repeat the same code over and over again. While it is possible (and pretty easy in modern systems) to simply copy the code by hand all over the place, it makes all of your program source files very large and repetitious, and tends to be error prone. Also, if you have to fix something that is copied to hell and gone, you need to fix it everywhere you have it - which is really error prone.

One solution is to automate copying the source. This is basically what #include does: it sticks a copy of the included file into the source code at the point where it is included, verbatim. Whatever was in the included file will show up in the program where the #include directive was. In fact, most of the job of the preprocessor is the replace one piece of text with another one, then hand the result on to the compiler proper.

This is a bit better, but it still has problems. First off, if you include all of the source code, you end up having to compile all of the code in those source files you've included - again and again and again. This is a slow process even today; in the days of yesteryear, it would have made compiling "Hello, World!" an all day event. And since you would be including a lot of code that you don't actually end up using, the program size grows like a cancer in your disk space.

What you really want is a way to copy the program functions, objects, etc. without having to recompile them every time, and pick out only the parts you need. Enter the linkage editor, or linker as it's usually called. This can take different pieces of compiled programs ('object code') and tie them all together into a nice like executable package, adding only the parts you need. If you want to get really fancy, it can even wait until you actually run the program to link the really common parts, meaning that if you have five programs using a shared function, you only need one copy in memory (though you only want to do this with very common things, since indiscriminate dynamic linking can slow programs down a lot). Now you can have a library, a file composed of pre-compiled object code that any program can use. A lot of the things which you probably think of as being part of C++ (e.g., the string and iostream classes, almost of the the functions you use) are actually part of a standard library, not the core language.

(HystericalHistorical note: Linkers actually came before preprocessors, and in fact before compilers or even assemblers (the same is true of interpreters, curiously enough, though they were special-purpose ones for handling things like floating-point math and 'interpreted' a sort of bytecode). The term 'compiler' originally referred to what we now call a linker, because it compiled a list of routines to add to an executable binary image - this was back in the days when men were men and programs were written with toggle switches - because otherwise you'd spend a lifetime punching in a simple addition routine.)

Of course, there are still problems with this, the biggest one being that your source file doesn't know what is defined in the libraries and the other parts of your program until it's linked, meaning that it would have no way of knowing if you really meant to call pow(2, "foo") until the linker goes bonkers on you trying to find a function named 'pow' that takes an integer and a character string as an argument - rather than that other one which takes two doubles. So we need to declare all of the functions etc. before we can use them, in every file that uses the functions... what a hassle...

But wait, we've still got #include! We can create a file of nothing but declarations - a header file - which solves the problem of having to add all of those tedious prototypes without having to repeat ourselves any more than we have to.

There are still some problems, mind you. If you try to get clever and stick some actual program code in a header file, and that header file is included in more than one place in a program, the linker will have a fit trying to figure out which function 'quux(int, int)' the the real McCoy, even if the source code for them is the exact same thing. This means that header files have to be declarations and nothing but (there's a few weird exceptions involving things like macros - which are actually inserted into the source code directly by the preprocessor - and templates - which are a safer and less annoying type of macro, though C++ programmers tend to get sniffy about it when freaky Lisp hackers like me point that out - but that's getting ahead of ourselves). You can even get in trouble if you have the same header included in two places in the same source file, as you'd be declaring the same thing twice, which has led to some funny tricks involving the conditional compilation directives in (yet again) the pre-processor to make sure it can't happen.

There's also the matter of telling the linker itself where to get the different pieces. Most linkers have options for this, but if you have to write out the whole list of files to link together in a large project every time you try to compile it, your fingers will wear away to nubs, and your bound to screw it up about a quarter of the time anyway. So this, too, get automated away: makefiles (or project files in a lot of newer systems) are scripts telling the linker where to go and what to do when it gets there. They can also do a los of the other scut work, like checking to see if a file has been changed (so that it doesn't compile it again) and cleaning up all of the temporary files after it's done.

But all of this amounts to nothing if a) the program is small enough to fit into a single file without making your eyes glaze over reading it, and b) you aren't going to be re-using the code anywhere else. In that case, you may as well just stick it all in one big file and be done with it - unless, of course, the whole point of the exercise is to show you about all the stuff I just rattled off to you. ANY QUESTIONS!?!

For further information, consult your pineal gland. Or don't, see if I care fnord.

#### Comments on this post

• ryon420 agrees : Your posts are probably the best around the shed. You need more rep.
• ShellyCat agrees : Very funny and explains some very complex stuff quite clearly! (When I get into reusable code, I will come here first to get my head screwed on straight.) You should do some professional writing!
Last edited by Schol-R-LEA; March 13th, 2008 at 01:39 AM.
15. To give your teacher the benefit of the doubt, he most likely taught himself programming using a book. Unfortunately, a number of C/C++ programming books use the method of including source files (eg, .CPP files).

Even though those authors should have known better, presenting that approach did solve a sticky problem for them. If you are writing a general-purpose programming book -- ie, one that is not tied to a single development environment (eg, Microsoft Visual Studio), but rather is meant to be used in any C/C++ development environment -- , then your examples need to be able to compile and run on any operating system using any compiler. The author immediately runs into a problem when he starts to present multiple-source-file projects, because every compiler IDE manages projects differently. In a book that targets a specific version of a specific IDE (that's right! not only does it differ between IDEs, but also between different versions of the same IDE), the author can and must describe how to create and manage a project. But when the reader could be using any possible IDE, the author simply cannot instruct every reader in the details of project management.

Rather than addressing that problem and offering a proper solution, too many authors have resorted to quick-and-dirty fixes, such as including all the other source files into the main source file. And as a result, all readers who only learned from those books and never got any real-world experience will end up walking away thinking that including .cpp files is what every C++ programmer does.

Something you should know -- and this applies to college as well as to high school -- is that the person teaching a class is not necessarily an expert in that subject. A junior-high (I think you call it "intermediate" nowadays) teacher once told us about an imposter who posed as different professionals; he said the easiest one to fake was being a college professor, because all he had to do was to read a few chapters ahead of the students. I do not at all intend to belittle the teaching profession. It takes a lot of work and planning to teach a class. Even though some instructors only know a little more than you do, that can still be enough for you to learn that little bit more. And if your questions should exceed your teacher's knowledge, then a good teacher will know how to go find the answer.

#### Comments on this post

• Schol-R-LEA agrees : The quote was from Frank Abnegale if I recall correctly. Given that he really was a jack-of-all-trades genius - how many people could succeed in so many fields, even by fraud - generalizing may not be a great idea, but for the most part, he was right
Page 1 of 2 12 Last