Most of this I have not written. The only part I am supposed to add things to is Triangle_main.cpp, anything under the TODOs are part of my assignment. I am getting undefined references to Triangle::SetHeight/SetBase/GetArea class member functions and I have finally lost my sanity trying to figure out what I have written that is wrong. I am posting the other .h and .cpp files that go with this.
I fixed it! It was a CodeBlocks issue. When I ran the code through the ZyBooks(the publisher we are using for my class) compiler it ran just fine.
Now, the ZyBooks editor/compiler does not give you any feedback on your code so clearly I need to use a different source to debug things. Can anyone tell me why I was getting these error messages out of CodeBlocks?
#include <iostream>
#include "Triangle.h"
usingnamespace std; // <--- Best not to use.
int main(int argc, constchar* argv[]) // <--- If you are not using the parameters you do not need them.
{
Triangle triangle1;
Triangle triangle2;
double userBase, userHeight;
// TODO: Read and set base and height for triangle1 (use SetBase() and SetHeight())
cin >> userBase; // <--- These 2 statements need a prompt.
cin >> userHeight;
triangle1.SetBase(userBase);
triangle1.SetHeight(userHeight);
// TODO: Read and set base and height for triangle2 (use SetBase() and SetHeight
cin >> userBase; // <--- These 2 statements need a prompt.
cin >> userHeight;
triangle2.SetBase(userBase);
triangle2.SetHeight(userHeight);
// TODO: Determine larger triangle (use GetArea())
cout << "Triangle with larger area:\n"; // <--- Prefer to use the new line (\n) over the "endl"s.
if (triangle1.GetArea() < triangle2.GetArea())
{
cout << "Triangle 2\n";
triangle2.PrintInfo();
}
if (triangle2.GetArea() < triangle1.GetArea())
{
cout << "Triangle 1\n";
triangle1.PrintInfo();
}
// TODO: Output larger triangle's info (use PrintInfo())
}
In the "Triangle.cpp" file use the C++ version "<cmath>" over the C version "<math.h>".
Andy thank you for the reply! I have taken some of your points and made some modifications and decided to integrate all of the files into one cpp file. I know this is not what a professional would ultimately use, but in an attempt to understand what you have pointed out this is a little easier, I will break it up again after I get it.
I think I understand why you would use n\ over endl. For high performance code endl would be a terrible thing to use because you are clearing the buffer every time it is used and that would be really inefficient.
Now I supposed I have another question, under what conditions do you want to clear the buffer? If it is to conserve memory how do you know you are using too much of it?
I did not mean for you to put everything in 1 file, but if it helped then it was worth it. When I put the 3 files in MSVS 2017 it compiled and worked. So I was thinking that maybe in your case you see 3 files, but the ".cpp" for the class functions may not have been compiled and at link time there was nothing to link to. Thus the error that "main" is trying to call a function that did not exist.
I do have Code::Blocks that I can use, but I am not that familiar with it. In the past I do not recall any problems with using multiple files.
I have not tried it yet, but the changes I see in "main" look good.
As for using "\n" over "endl". I do believe there was a time when the 2011 standards did not empty the buffer using "\n". This is based on the MSVS 2015 I was using at the time. When I upgraded to the 2017 version using the 2014 standards the "\n" seemed to work the same as the "endl". I would not call it "for high performance", but making better use of the language.
The bigger part of this comes from what I have read here and accepted as normal.
As for the: usingnamespace std:: there has been much written here. Also there should be much that can be found in the whole Web.
What it comes down to is that you are putting the entire standard name space in your program and when you compile you are telling to put "std::" in front of every variable and function name to see if it is in the standard name space. If it is then the compiler will use that instead of what is in your program. Quite often this is a problem when a function in the standard name space requires parameters of 1 type and your function has parameters of a different type. So the function call does not match. Also you are likely to get an warning saying the something is ambiguous meaning that the compiler does not know which function you are trying to use.
I look at it this way. In the beginning you have to learn "std::cout", "std::cin" and "std::endl". Next may be "std::string" and "std::getline" and anythinf else that is available in the "string class". Doing this a little bit at a time it is not that hard to learn. The other way is to wait until "namespace" is covered in a class and you would have to learn everything at 1 time. My-self I prefer a little at a time over all at once.
When it comes to clearing the buffer it really depends on your code. Formatted input: std::cin >> aVariable will leave the "\n" in the buffer, but followed by another formatted input it will ignore an white space, which includes the "\n", until it finds something to extract. The other problem you will find is that formatted input will extract from the buffer until it finds white space, usually a space, or "\n" whichever comes first. This tends to work great for numbers, but not when you want to put "first last" into a string. Formatted input will put "first" into the string stopping at the space leaving this in the buffer for the next input to use.
The opposite is "std::getline" or unformatted input. This takes whatever you type and stores it in the variable, which is a "std::string" type variable. It also extracts the "\n", but discards it as the string does not need it leaving the buffer empty.
In the end it depends on your code. Formatted input followed be unformatted input needs the buffer cleared otherwise the unformatted input will read the "\n" and move on thinking it has everything it needs and skipping your input. Unformatted input followed by formatted inpu is not a problem.
As far as to "conserve memory" the buffer used for input or output is already defines and has a size. Whether it contains "\0"s or some other characters makes no difference. Clearing anything that may be in the buffer does not change its original size, so there is nothing to conserve.
@Icebrand,
Regarding namespace std;
You have probably seen people saying things like std::cout, std::cin, and std::endl;. Well, those are defined in what's called the standard namespace. You'll probably learn more about it if you Google a definition of it, but basically what usingnamespace std; does is, it tells the compiler that for everything in the standard namespace, just ignore if someone omits the scope ( the std::).
Like this:
1 2 3 4 5 6 7 8 9
#include <iostream>
int main ()
{
// std:: means "In the standard namespace"
std::cout << "Hello world!" << std::endl;
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13
#include <iostream>
// Tells the compiler to automatically use the standard namespace
// on things like cout, cin, endl, string, etc.
usingnamespace std;
int main ()
{
// Now it automatically uses the standard namespace.
cout << "Hello world!" << endl;
return 0;
}
Note: If you are using macOS, I can give you some tips on how to debug C++ programs using the Terminal application.
Edit:
I just noticed that Handy Andy already explained it in his post. Whoops.
I don't think I've written a program with more than 200 lines or so, so 500 is huge for me. But I am aware that there are much bigger programs out there. Could you shoot me a link to a thread where it's explained? That would be much appreciated!
Thanks!
max
P.S. Hope you didn't get coffee on your keyboard ;).
Search terms: Using Declarations, Using Directive, or Full Scope Resolution.
Here are a few...
http://cplusplus.com/forum/general/250849/
http://www.cplusplus.com/forum/beginner/9181/#msg42419
http://www.cplusplus.com/forum/beginner/21249/
The important thing is understanding what is happening with the different things...
@agent max
With background you can understand why using namespace often invites portability issues. Typically the resulting problems result in compilation errors, but in the worst cases a program will compile to contain actual runtime errors.
Feel free to use it habitually if you enjoy telling your customers "but it works on my machine" while fixing your broken software. Otherwise, think about it first: there are cases where using namespace is quite risk-free.
There are people here who deal with programs that are 100 MLOC. I have heard stories about code that takes 24hrs to compile ! To put that into perspective, if compile the latest version of gcc with all the languages gcc can do, on my machine that takes about 1 hr
A long time ago I read that Excel, Word etc were about 1 MLOC, not sure how true that is these days.
Writing std::copy is explicit, whereas copy is not: is it boost::copy or some other copy from some other place you don't know about yet? The compiler might find an unexpected version.
The other thing that is convenient, is to use a namespace alias: