C++ Unexpected number output - c++

EDIT: Fixed the problem thanks to advice from below. Changed the return type of evaluation() from an int to a void.
I'm learning how to use classes, and I'm experiencing a problem. I keep getting an output that says:
0
They are not equal.
4469696
Where is that last number coming from? It should be somewhere after
the line
std::cout << Thing.evaluation(Thing.getValue()) << std::endl;
but I don't see anything that could possibly be outputting that value. Is it memory leakage?
#include <iostream>
#include <conio.h>
class classTest
{
public:
int equivalency(int x, int y)
{
if (x == y)
{
value = 1;
} else
{
value = 0;
}
}
int evaluation(int z)
{
if (z == 0)
{
std::cout << "They are not equal." << std::endl;
} else
{
std::cout << "They are equal." << std::endl;
}
}
int getValue()
{
return value;
}
private:
int value;
};
int main()
{
int a = 0, b = 0;
classTest Thing;
std::cout << "Enter two numbers for comparison." << std::endl;
std::cin >> a >> b;
Thing.equivalency(a, b);
std::cout << Thing.getValue() << std::endl;
std::cout << Thing.evaluation(Thing.getValue()) << std::endl;
getch();
return 0;
}

In evaluation() you print the expected messages. Then you don't return anything from this function although it is declared to return int, i.e., you get undefined behavior. Further more, you actually point the random result since you output the result of the call:
std::cout << Thing.evaluation(Thing.getValue()) << std::endl;
BTW, don't use std::endl! If you want a newline, use '\n', if you want to flush the buffer use std::flush. Unnecessary use of std::endl is a relatively frequent source of major performance problems.

Related

Test an integer value to determine if it is odd or even in C++

I have to write a program to test an integer value to determine if it is odd or even, and make sure my output is clear and complete. In other words, I have to write the output like "the value 4 is an even integer". I was also hinted that I have to check the value using the remainder modulo.
The issue I have is with the scanf() function. I get a syntax error:
'%=' expected a ')'
How do I fix this?
#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
int main()
{
int number = 0;
cout << "enter an integer ";
int scanf(%=2 , &number);
if (number == 0)
cout << "the value" << number << "is even";
else
cout << "the value" << number << "is odd";
return 0;
}
You are using scanf() incorrectly (read the scanf() documentation on cppreference.com). The first parameter expects a null-terminated string containing the format to scan, but you are not passing in anything that even resembles a string. What you are passing in is not valid string syntax, per the C++ language standard. That is why you are getting a syntax error.
You need to change this line:
int scanf(%=2 , &number);
To this instead:
scanf("%d", &number);
Though, in C++ you really should be using std::cin instead for input (you are already using std::cout for output):
std::cin >> number;
Try this:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
int number = 0;
cout << "enter an integer ";
if (cin >> number)
{
if ((number % 2) == 0)
cout << "the value " << number << " is even";
else
cout << "the value " << number << " is odd";
}
else
cout << "the value is invalid";
return 0;
}
I know this question is a little dated, however, if you are able to use modern C++ features. You can write a constexpr helper function such as this:
#include <cstdint>
constexpr bool isEven(uint32_t value) {
return ((value%2) == 0);
}
Then in your main function, you can traverse through a loop of N integers and output your display such as:
#include <iostream>
#include <iomanip>
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << " is "
<< (isEven(i) ? "even" : "odd") << '\n';
}
return 0;
}
It's literally that simple. Here's another nice feature of using the constexpr helper function... You can also format your output as such:
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << ": "
<< std::boolalpha << isEven(i) << '\n';
}
return true;
}
If you are looking for something that is more efficient than using the modulo operator you can bitwise & with the least significant digit... The code above would then become:
#include <cstdint>
constexpr bool isOdd(uint32_t value) {
return (value&1);
}
And using it would be very similar as above, just make sure you reverse the wording in your output to match that from the function being used...
#include <iostream>
#include <iomanip>
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << " is "
<< (isOdd(i) ? "odd" : "even") << '\n';
}
return 0;
}
Again you can use the std::boolalpha manipulator to get this kind of output:
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << ": "
<< std::boolalpha << isOdd(i) << '\n';
}
return true;
}

How can I build a proper constructor and destructor?

Question #1: How can I build a constructor set the value for (R,PoF,PoR)? I am trying to understand how constructor works but I guess I don't quite get it.
Question #2: Can I build destructor in this way, instead of the way I used in my program?
Circle::~Circle()
{
std::cout << "The fence would cost " << SwimmingPool.PerimeterP(r) << std::endl;
std::cout << "The road would cost " << SwimmingPool.AreaP(r) << std::endl;
std::cout << "Present by FF" << std::endl;
}
I just want the cost to come out by itself, but I don't know how should I create destructor to do so.
Here is my full code:
#include "stdafx.h"
#include "iostream"
const double PI = 3.1415926;
class Circle
{
public:
Circle();
double AreaP(int r);
double PerimeterP(int r);
~Circle();
private:
int R;
int PoF;
int PoR;
};
double Circle::AreaP(int r)
{
return ((r + R)*(r + R) - r*r)*PI*PoR;
}
double Circle::PerimeterP(int r)
{
return (r + R) * 2 * PI*PoF;
}
Circle::Circle()
{
int R = 3;
int PoF = 35;
int PoR = 20;
}
Circle::~Circle()
{
std::cout << "Present by FF" << std::endl;
}
int main()
{
int r;
Circle SwimmingPool;
std::cout << "Please input the radius of the Swimming Pool." << std::endl;
std::cin >> r;
std::cout << "The fence would cost " << SwimmingPool.PerimeterP(r) << std::endl;
std::cout << "The road would cost " << SwimmingPool.AreaP(r) << std::endl;
return 0;
}
You have:
Circle::Circle()
{
int R = 3;
int PoF = 35;
int PoR = 20;
}
That function creates three function local variables and sets their values. It does not initialize the members of the class. Change it to:
Circle::Circle() : R(30), PoF(35), PoR(20) {}
Always prefer to initialize in the initializer list instead of setting the values in the body of the constructor.
No, you may not use:
Circle::~Circle()
{
std::cout << "The fence would cost " << SwimmingPool.PerimeterP(r) << std::endl;
std::cout << "The road would cost " << SwimmingPool.AreaP(r) << std::endl;
std::cout << "Present by FF" << std::endl;
}
SwimmingPool is a variable in main. It cannot be used in the destructor. Besides, it does not make sense to print those messages in the destructor. It should simply be
Circle::~Circle()
{
}
Circle::Circle() : R(3), PoF(3), PoR(3) {};
Define the R, PoF, PoR as const int
The destructor must not throw an exception and generally you want it to release resources acquired by the object. Usually not the best place to be outputting stuff to stdout.
Don't use std::endl unless you want to flush the stream. Use '\n' instead.

commenting out cout statement causes different (and incorrect) output

I have never experienced anything like this. I was using a cout statement to help me debug a small program, and once I was satisfied with my code I commented out the cout. Now, the code no longer works. Below is the code with the cout commented out.
The intent of this program is to test the two hard coded boolean two dimensional arrays for having an odd number of true statements on each row. Thus, the first array should return true and the second array should return false. With the cout statement commented out both instead return false.
#include <iostream>
using namespace std;
template <size_t size_y>
bool findEvenDegrees(bool mapArray[][size_y])
{
bool returnValue;
for (int x=0; x<size_y; x++)
{
int result = 0;
for (int y=0; y<size_y; y++)
{
result = result + mapArray[x][y];
//the line below causes the problem
cout << mapArray[x][y] << "\t" << result << "\t" << x << endl;
}
if (result%2 == 1)
{
returnValue = false;
break;
}
}
if (returnValue== false)
{
return returnValue;
}
else
{
return true;
}
}
int main()
{
bool array1[][6] =
{
{false,true,true,false,false,false},
{true,false,false,true,false,false},
{true,false,false,true,false,false},
{false,true,true,false,true,true},
{false,false,false,true,false,true},
{false,false,false,true,true,false}
};
bool array2[][8] =
{
{false,true,true,false,false,false,false,false},
{true,false,false,true,false,false,false,false},
{true,false,false,true,false,false,false,false},
{false,true,true,false,true,false,false,false},
{false,false,false,true,false,true,true,false},
{false,false,false,false,false,true,false,true},
{false,false,false,false,true,false,false,true},
{false,false,false,false,false,true,true,false}
};
bool answer1 = findEvenDegrees(array1);
bool answer2 = findEvenDegrees(array2);
if (answer1 == true)
{
cout << "Array 1 has a even degree for every switch." << endl;
}
else
{
cout << "Array 1 has a odd degree for at least one switch." << endl;
}
if (answer2 == true)
{
cout << "Array 2 has a even degree for every switch.";
}
else
{
cout << "Array 2 has a odd degree for at least one switch.";
}
return 0;
}
You never initialize returnValue. If it happens to start out as false it will stay that way and the function will return false.
First, I cleaned up your code a little, and arrived at:
#include <iostream>
template <size_t S>
bool findEvenDegrees(bool (&themap)[S][S]) {
for( bool(&row)[S]: themap ) {
bool is_degree_odd = false;
for( auto col: row )
is_degree_odd ^= col;
if( is_degree_odd )
return false;
}
return true;
}
int main()
{
using std::cout;
using std::endl;
bool array1[6][6] = {
{false,true,true,false,false,false},
{true,false,false,true,false,false},
{true,false,false,true,false,false},
{false,true,true,false,true,true},
{false,false,false,true,false,true},
{false,false,false,true,true,false}
};
cout << "Array 1 has an "
<< (findEvenDegrees(array1) ? "even degree for every" : "odd degree for at least one")
<< " switch." << endl;
bool array2[8][8]= {
{false,true,true,false,false,false,false,false},
{true,false,false,true,false,false,false,false},
{true,false,false,true,false,false,false,false},
{false,true,true,false,true,false,false,false},
{false,false,false,true,false,true,true,false},
{false,false,false,false,false,true,false,true},
{false,false,false,false,true,false,false,true},
{false,false,false,false,false,true,true,false}
};
cout << "Array 2 has an "
<< (findEvenDegrees(array2) ? "even degree for every" : "odd degree for at least one")
<< " switch." << endl;
return 0;
}
In the process of cleaning it up, I eliminated the if(result%2 == 1) { resultValue = true; break; }, by effectively returning when I found the first odd-degree row. As I eliminated the resultValue variable, I also killed the "unitialized" bug mentioned by #sth.

C++ Recursive functions

I'm learning C++ and I have trouble with getting recursion working when a function is called by itself.
#include <iostream>
using namespace std;
int countdown(int y) {
if (y==1) {
return 1 && cout << y << endl;
}
else {
return countdown(y-1);
}
}
int main () {
cout << "Countdown from ten: " << endl;
cout << countdown(10) << endl;
}
Of course there are other ways to achieve this, but really I created this example to verify my own understanding of how functions are called recursively.
In the example I added && cout << y to verify if y is being passed to the function as 1, which always appears to be the case irrespective that I call the function as countdown(10).
Could someone tell me if I'm missing something obvious here please?
Your ' cout << y ' only executes if y has been tested to be one.
This version does what I think you want:
#include <iostream>
using namespace std;
int countdown(int y)
{
cout << y << endl;
if (y==1)
{
return 1;
}
else
{
return countdown(y-1);
}
}
int main()
{
cout << "Countdown from ten: " << endl;
cout << countdown(10) << endl;
}
Your call stack looks like this:
main
countdown(10)
countdown(9)
countdown(8)
countdown(7)
countdown(6)
countdown(5)
countdown(4)
countdown(3)
countdown(2)
countdown(1)
std::cout << 1 << std::endl;
If you want to see the whole countdown, move the output command in front of the if condition.
Also, your style of writing the output is very unidiomatic. Note that it only works because 1 %&& cout converts the cout to bool and bool can be converted to int. Please don't write code like that.

Input validation for Integer and Double data types

Because there was an error in the code when I posted this question, it is not a good question. I have deleted and replaced it with a link to a correct solution.
Correct Solution for Input Validation
cin.getline(buffer, '\n');
<-- is wrong, need buffer size.
cin.getline(buffer, 10000, '\n');
The simplest fix here is to set a limit on your 'cin.getline()' call so it doesn't overflow your buffer, or alternatively switch over to using a string class or some such like so:
#include <iostream>
#include <errno.h>
int main() {
std::string buffer;
double value;
char* garbage = NULL;
while (true) {
std::cin >> buffer;
std::cout << "Read in: " << buffer << std::endl;
if (std::cin.good())
{
value = strtod(buffer.c_str(), &garbage);
if (errno == ERANGE)
{
std::cout << "A value outside the range of representable values was returned." << std::endl;
errno = 0;
}
else
{
std::cout << value << std::endl << garbage << std::endl;
if (*garbage == '\0')
std::cout << "good value" << std::endl;
else
std::cout << "bad value" << std::endl;
}
}
}
return 0;
}