Reading from file and storing attributes gives wrong output - c++

I'm trying to read a text file that consists of the following three attributes;
RouterID, X-coordinate, Y-coordinate.
A brief snippet of the txt file is shown below;
100 0 0
1 20.56 310.47
2 46.34 219.22
3 240.40 59.52
4 372.76 88.95
Now, what I'm trying to achieve is to make a node for every RouterID and store its corresponding x and y co-ordinates. For this purpose, I have created the following class;
class Node {
public:
float routerID;
float x;
float y;
void set_rid (float routerID) {
routerID = routerID;
}
void set_x_y (float x, float y) {
x = x;
y = y;
}
};
And I have the following which performs the job of creating a new node for every routerID;
const std::string fileName = "sampleInput.txt";
std::list<Node> nodeList;
int main (void) {
std::ifstream infile(fileName);
float a(0);
float b(0), c(0);
//This reads the file and makes new nodes associated with every input
while (infile >> a >> b >> c) {
Node newNode;
newNode.set_rid (a);
newNode.set_x_y (b, c);
std::cout << "newNode " << "rid = " << newNode.routerID << " x = " << newNode.x << " y = " << newNode.y << std::endl;
nodeList.push_back(newNode);
}
I'm performing the following line inside my while loop just to check whether or not the values being assigned are correct or not.
std::cout << "newNode " << "rid = " << newNode.routerID << " x = " << newNode.x << " y = " << newNode.y << std::endl;
When I compile and run the code, I get the following as my output for all of them;
newNode rid = -1.07374e+008 x = -1.07374e+008 y = -1.07374e+008
I've just started learning C++ last week and this is my first "big" program that I am trying to code. Could anyone please point me in the right direction?

void set_rid (float routerID) {
routerID = routerID;
}
This doesn't do what you seem to think it does. It assigns the parameter to itself; the value of this->routerID remains unchanged. Same with set_x_y. Just give the method parameters some names that are different from those of data members.

Another to distinguish class variables from input parameter is by using the keyword this. thus you can make a reference to class variables by calling this.routerID, this.x and this.y

Related

How is "a" used in my program?

new to learning c++ and I was wanting to understand the program ive practiced. I have a section of code I want to understand but im kind of lost.
#include "stdafx.h";
#include <iostream>;
// getValueFromUser will read a value in from the user, and return it to the caller
int getValueFromUser()
{
std::cout << "Enter an integer: ";
int a;
std::cin >> a;
return a;
}
int main()
{
int x = getValueFromUser(); // first call to getValueFromUser
int y = getValueFromUser(); // second vall to getValueFromUser
std::cout << x << " + " << y << " = " << x + y << std::endl;
return 0;
}
Im just wanting to know how " int a " comes into play here. If someone could help it would be appreciated.
You declare an uninitialized variable of type int with identifier a:
int a;
The user provides a value to a.
std::cin >> a;
A copy is returned from the function:
return a;
Calls to the getValueFromUser() will create a temporary a,
assign it to user input, and return it each time.
In c++ you have to declare variable (providing the type and name) before it's first use.
std::cin has to put it's output somewhere and that's why you need this additional variable.

Uninitialized Local Variable

I'm new and just learning C++ and came across this problem that I've spent maybe an hour trying to fix and researching answers on but I cant seem to figure out what I'm doing wrong. I'm using Visual Studios as my IDE, the most recent version.
#include "stdafx.h"
#include <iostream>
#include "constant.h"
//height of the tower
double towerHeight(double x)
{
using namespace std;
cout << "Enter a height for the tower" << '\n';
cin >> x;
return x;
}
//the number of seconds since the ball has been dropped to determine the distance
double secondsSinceDrop(double x)
{
using namespace std;
cout << "How long has it been since you dropped the ball (Seconds): ";
cin >> x;
return x;
}
//finds how far off the ground the ball is
double currentBallHeight(double x, double y)
{
return y * constant::gravity - x;
}
//prints how far off the ground the ball is
void printResult(double x, double y)
{
using namespace std;
if (currentBallHeight(x, y) < 0)
cout << "At " << y << " the ball is on the ground." << '\n';
else
cout << "At " << y << " the ball is at: " << currentBallHeight(x, y) << '\n';
}
int main()
{
double x = towerHeight(x);
double y = secondsSinceDrop(x);
printResult(x,y);
return 0;
}
This is the Error Code
- chapter 2 comprehensive quiz (part 2).cpp(46): error C4700: uninitialized local variable 'x' used
-Line (46) is - double x = towerHeight(x);
I've been getting this and I've changed my code around to get it down to just this one error but i cant figure out how to fix it. Its probably something simple and I'm dumb for overlooking it but any help would be greatly appreciated.
These lines will be throwing errors
because the variable 'x' you are sending as an argument does not exist in the scope of main
int main()
{
-> double x = towerHeight(x);
-> double y = secondsSinceDrop(x);
printResult(x,y);
return 0;
}
Instead you could try something like this.
#include "stdafx.h"
#include <iostream>
#include "constant.h"
using namespace std;
//height of the tower
double towerHeight()
{
double height;
cout << "Enter a height for the tower" << '\n';
cin >> height
return height;
}
//the number of seconds since the ball has been dropped to determine the distance
double secondsSinceDrop()
{
double seconds;
cout << "How long has it been since you dropped the ball (Seconds): ";
cin >> seconds;
return seconds;
}
//finds how far off the ground the ball is
double currentBallHeight(double x, double y)
{
return y * constant::gravity - x;
}
//prints how far off the ground the ball is
void printResult(double x, double y)
{
if (currentBallHeight(x, y) < 0)
cout << "At " << y << " the ball is on the ground." << '\n';
else
cout << "At " << y << " the ball is at: " << currentBallHeight(x, y) << '\n';
}
int main()
{
double height = towerHeight();
double seconds = secondsSinceDrop();
printResult(height, seconds);
return 0;
}
Some tips that I would recommend
Declare your variables as much as relevant to you instead of using 'x/y/z'
There is no need to add the using namespace std; inside each function
Your first line of code in main() is double x = towerHeight(x);, what value of x are you sending to the function, when you have not initialized it.
When you are using a variable without initializing the value of it is undefined.
You can pass the variable as a reference to your function and accept the values inside it.
//height of the tower
void towerHeight(double &x)
{
using namespace std;
cout << "Enter a height for the tower" << '\n';
cin >> x;
}
//the number of seconds since the ball has been dropped to determine the distance
void secondsSinceDrop(double &y)
{
using namespace std;
cout << "How long has it been since you dropped the ball (Seconds): ";
cin >> y;
}
int main()
{
double x = 0.0, y = 0.0;
towerHeight(x);
secondsSinceDrop(y);
printResult(x, y);
return 0;
}
You seem to be struggling to connect the mental dots on what the computer is doing when you
declare variables with an initial value
define function parameters
return a value from a function
Not sure how this question will fair with the SO community as the preference is for Q/A that is succinct and reusable (maybe some editing can help) but for your benefit let me explain some of these concepts.
Let's start with a variable declaration
int x = 5;
int y = x;
When you define int x; it creates a space in RAM for an integer (4 bytes). Adding the = 5 initializes it immediately. It's important that the value on the right side of = (5 in this case) is known before the computer tries to make space for x.
It's fine to use values that aren't constant for variables like this (notice the second line in the example) but x has to be known before you declare y. In other words, this would obviously be a problem:
int y = x;
int x = 5;
For this same reason, the line: double x = towerHeight(x); is problematic because you're using x when you call towerHeight before ever defining x
When you define a function's parameters:
double towerHeight(double x) {
This tells the computer that you are going to copy the value from whatever called towerHeight to a new place in RAM and call it "x". This means that the value outside of the function doesn't get modified. Consider the following example:
double towerHeight(double x) {
x = 5;
std::cout << x << std::endl; // outputs 5
}
int main() {
double x = 10;
towerHeight(x);
std::cout << x << std::endl; // outputs 10
return 0;
}
Even though x was changed in towerHeight that was a "different copy of x" which also happened to be called the same name.
When you return a value from a function, in the same manner as passing a function argument, the return value is copied and used in places of the function call. Let's modify the previous example slightly:
double towerHeight(double x) {
x = 5;
return x;
}
int main() {
double x = 10;
x = towerHeight(x); // returns the value "5"
std::cout << x << std::endl; // Outputs "5"
return 0;
}
You can think of towerHeight(x) being replaced by "5" so the code would read x = 5;
Conclusion
You should try and use different variable names for
function arguments (the variables/values you pass to the function)
function parameters (what they are called inside the function)
to avoid this kind of confusion. Though there may be times where using the same name makes sense (i.e. passing by reference, which is another question). It's important for you to be aware of what's really going on.
Here is what you probably intend to do:
double towerHeight()
{
double height;
std::cout << "Enter a height for the tower" << std::endl;
std::cin >> height;
return height;
}
double secondsSinceDrop()
{
double seconds;
std::cout << "How long has it been since you dropped the ball (Seconds): ";
std::cin >> seconds;
return seconds;
}
double currentBallHeight(double y0, double t)
{
return y0 - (constant::gravity * t * t / 2);
}
void printResult(double y0, double t)
{
double currentHeight = currentBallHeight(y0, t);
if (currentHeight < 0)
std::cout << "At " << t << "s the ball is on the ground." << std::endl;
else
std::cout << "At " << t << "s the ball is at: " << currentHeight << std::endl;
}
int main()
{
double y0 = towerHeight();
double t = secondsSinceDrop();
printResult(y0, t);
return 0;
}
Summarizing what I've changed:
Renamed x to y0 since y(0)/h(0) is typically used for "initial height" in physics classes, and similarly y with t (though time would be an even better name).
Don't pass anything to towerHeight or secondsSinceDrop; you're not trying to give those functions something, you're trying to get something out of them.
Move the definition of x from a function parameter to a local variable defined in the function for towerHeight and secondsSinceDrop
Removed the duplicated call to currentBallHeight (no need to do the same math twice, it takes time to crunch numbers after all, however small in this case)
Rewrote for proper usage of std::cout and std::endl
Rewrote the currentBallHeight equation to match constant free-fall kinematics (y(t) = y(0) - 0.5g * t^2) as an added bonus (assuming constant::gravity > 0)
At some point it will be valuable for you to become aware of the more technical terminology and definitions for the concepts I've outlined here. Here are some recommended readings (just to get you started; keep learning, always):
Sequence Points
Parameters and Arguments
Passing by Reference vs by Value
Passing pointers vs by Reference
Making sure you understand what using namespace std; does and why you should never use it
Rewrite your function as following:
//height of the tower
double towerHeight()
{
double x;
using namespace std;
cout << "Enter a height for the tower" << '\n';
cin >> x;
return x;
}
and in int main(){} rewrite following line:
double x = towerHeight();
I guess this will do but you can actually modify your double secondsSinceDrop(double x); function this way as it doesn't really need a double value as parameter.

Dev c++ 5.11 on Windows 8 Produces wrong answer

#include<iostream>
#include<conio.h>
class Number
{
private:
int x, y;
public:
Number()
{
x = y = 100;
}
void avg()
{
std::cout<<"x = "<<std::cout<<x;
std::cout<<std::endl;
std::cout<<"Y = "<<std::cout<<y;
std::cout<<std::endl;
std::cout<<"Average = "<<std::cout<<(x+y)/2;
}
};
main()
{
Number n;
n.avg();
}
This programme runs but shows wrong answer, may be showing addresses of memory locations instead of showing the assigned values of 100. Please correct me why it is behaving like this?
std::cout << "x = " << std::cout << x;
is wrong. You need
std::cout << "x = " << x;
Otherwise, the std::cout stream object in ...<< std::cout is implicitly converted to a (void*) when invoking operator<< on it, and therefore the pointer (an address) is displayed.
The conversion to void* exists for historic reasons (the safe bool idiom), but in C++11 was removed, due to the introduction of explicit conversion operators, so your code should not compile in C++11.

C++ Can't figure out output for a class that holds player information. It outputs garbage

I've been pulling my hair out trying to figure out this program. The class has to hold 3 player's info and output their info. My output function is not outputting from my set/get functions. Also, if I output the array indexes the program crashes (that's the array indexes are commented out in the Output function).
edit: I'll just show one profile to keep the code smaller
Any help is appreciated.
#include <cstdlib>
#include <iostream>
using namespace std;
class PlayerProfile
{
public:
void output();
void setName1(string newName1); //player's name
void setPass1(string newPass1); //player's password
void setExp1(int newExp1); //player's experience
void setInv1(string newInv1[]); //player's inventory
void setPos1(int newX1, int newY1); //player's position
string getName1();
string getPass1();
int getExp1();
string getInv1();
int getPos1();
private:
string name1;
string pass1;
int exp1;
string inv1[];
int x1;
int y1;
};
int main(int argc, char *argv[])
{
PlayerProfile player;
cout << "This program generates three player objects and displays them." << endl;
cout << endl;
player.output();
system("PAUSE");
return EXIT_SUCCESS;
}
void PlayerProfile::setName1(string newName1)
{
newName1 = "Nematocyst";
name1 = newName1;
}
void PlayerProfile::setPass1(string newPass1)
{
newPass1 = "obfuscator";
pass1 = newPass1;
}
void PlayerProfile::setExp1(int newExp1)
{
newExp1 = 1098;
exp1 = newExp1;
}
void PlayerProfile::setInv1(string newInv1[])
{
newInv1[0] = "sword";
newInv1[1] = "shield";
newInv1[2] = "food";
newInv1[3] = "potion";
inv1[0] = newInv1[0];
inv1[1] = newInv1[1];
inv1[2] = newInv1[2];
inv1[3] = newInv1[3];
}
void PlayerProfile::setPos1(int newX1, int newY1)
{
newX1 = 55689;
x1 = newX1;
newY1 = 76453;
y1 = newY1;
}
string PlayerProfile::getName1()
{
return name1;
}
string PlayerProfile::getPass1()
{
return pass1;
}
int PlayerProfile::getExp1()
{
return exp1;
}
string PlayerProfile::getInv1()
{
return inv1[0], inv1[1], inv1[2], inv1[3];
}
int PlayerProfile::getPos1()
{
return x1, y1;
}
void PlayerProfile::output()
{
cout << "Player Info - " << endl;
cout << "Name: " << name1 << endl;
cout << "Password: " << pass1 << endl;
cout << "Experience: " << exp1 << endl;
cout << "Position: " << x1 << ", " << y1 << endl;
cout << "Inventory: " << endl;
/*cout << inv1[0] << endl;
cout << inv1[1] << endl;
cout << inv1[2] << endl;
cout << inv1[3] << endl; */
}
This is the output that I am getting:
This program generates three player objects and displays them.
Player Info -
Name:
Password:
Experience: -2
Position: 3353072, 1970319841
Inventory:
Press any key to continue . . .
I'm sorry if I sound like an idiot, this is the first time I have programmed with classes and I am very confused.
First:
You do not have a constructor declared or defined in your class so when you compile, the compiler provides you with a default constructor.
The line
PlayerProfile player;
calls the default constructor provided by the compiler. This default constructor only allocates memory for your class member variables, but does not set their values. This is why name1, pass1, exp1, x1, y1 are not outputting what you expect.
Second:
C++ will not call get or set functions for you, and I think you are misunderstanding how c++ functions work.
this
void PlayerProfile::setName1(string newName1)
{
name1 = newName1;
}
is a function definition. You do not need to assign newName1 inside the function. It's value is passed to the function when a line like
setName1("Nematocyst");
is executed.
If you write a constructor, you can use it to call your set functions, and pass them the values you want to set member variables to.
If you do not want to write a constructor, you can call class functions/methods from main with:
player.setName1("Nematocyst");
Third:
Your program crashes because you are not using arrays properly. Here is a tutorial on how to declare an array and access it's contents.
Generally, I think you are trying to run before you know how to walk. Try not to get frustrated. Learn how arrays work, how functions work, and then how classes work. I hope this is not your homework assignment!

Sending a vector of stuct objects through the 'next_permutation' algorithm fails to build

I am having trouble with getting a brute-force algorithm to work. As you can see from my code below, I am trying to evaluate a vector of structs and find the most efficient way to order a series of timed events. Here is my simple struct layout whose objects I am placing in the 'part1Vec' vector:
struct person
{
float swim;
float bike;
float run;
float bikeRun;
person();
person(float swim, float bike, float run)
{
this->swim = swim;
this->bike = bike;
this->run = run;
this->bikeRun = bike + run;
};
};
However, when I compile I get an error within the algorithm class that I have supposedly traced to this line:
while (next_permutation(part1Vec.begin(), part1Vec.end()))
the error message I get is this:
//Invalid operands to binary expression ('const person' and 'const person')
I believe I have the next_permutation function implemented correctly, but I do not understand why it is giving me this error. Any help would be appreciated, thanks. Here is my full code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct person
{
float swim;
float bike;
float run;
float bikeRun;
person();
person(float swim, float bike, float run)
{
this->swim = swim;
this->bike = bike;
this->run = run;
this->bikeRun = bike + run;
};
};
//function declarations and global variables
vector<person> part1Vec;
vector<person> highestVec;
float highestRating;
float tempRating;
float rating(vector<person> vector);
int main()
{
//PART 1
//make objects
person one(20, 25, 20), two(35, 20, 15), three(40, 20, 30);
//insert into vector
part1Vec.push_back(one);
part1Vec.push_back(two);
part1Vec.push_back(three);
cout << "_________swim__bike__run__" << endl;
for (int i=0; i<part1Vec.size(); i++)
{
cout << "Vector #" << i+1 << ": "
<< part1Vec[i].swim << " "
<< part1Vec[i].bike << " "
<< part1Vec[i].run;
}
cout << endl << "Calculating..." << endl;
//Next permutation function
while (next_permutation(part1Vec.begin(), part1Vec.end())) //Invalid operands to binary expression ('const person' and 'const person')
{
//initialize highestVec
if (highestVec.size() == 0)
{
highestRating = rating(part1Vec);
highestVec = part1Vec;
}
//if Highest Rating is less than current permutation, update.
else if (highestRating < (tempRating = rating(part1Vec)) )
{
highestVec = part1Vec;
highestRating = tempRating;
}
}
cout << "Best Solution:" << endl;
for (int i=0; i<part1Vec.size(); i++)
{
cout << "Vector #" << i+1 << ": "
<< highestVec[i].swim << " "
<< highestVec[i].bike << " "
<< highestVec[i].run;
}
cout << endl << "Rating: " << highestRating << endl;
return 0;
}
float rating(vector<person> thisVector)
{
float rating = 0;
float swimSum = 0;
for (int i=0; i<thisVector.size()-1; i++)
{
swimSum += thisVector[i].swim;
if (rating < swimSum + thisVector[i].bikeRun)
rating = swimSum + thisVector[i].bikeRun;
}
return rating;
}
Kyle Y., did you understand what chris meant?
I hope Chris won't mind, but I'll take the liberty of elaborating just in case.
First up, say what compiler you're using. One reason is that they give different error messages. And in this instance, Invalid operands to binary expression ('const person' and 'const person') was kinda useful but not as useful as it could be. If I ran this through gcc, for example, it'd probably tell me something more like that std::next_permuation was looking for an undefined operator.
std::next_permuation uses a well ordering to generate permutations. So it needs arguments of types with an order defined on themselves, and so that the algorithm will always terminate, a consistent order (an ordering is inconsistent if a<(b) and b<(a) is possible, which is generally inadvisable regardless).
That's what chris is referring to, and the way you do that in C++ with say struct types like yours for which order is not already defined by a base class, is to override bool operator<(... in the struct.
Because you only need the ordering for your permutation generation, any old ordering will do as long as: everything is ordered and the ordering is consistent, as above.
See here for your code again with that override and a few unsigned ints in where they should be, note:
bool operator<(const person& rhs) const {
return (this->swim + this->bike + this->run) < (rhs.swim + rhs.bike + rhs.run);
}
Best.