Very weird behaviour with my C++ vector [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I've been debugging this for a long time now - but I have no clue what the issue is.
I get a name from the console (via std::cin) and then proceed to create a new Player object with it. Then I pass the new object to the Gameboard to be added to a std::vector<J> where J is part of a template. Here's the code:
main.cpp
Gameboard<Tile,Player,5,5> board = Gameboard<Tile,Player,5,5>();
std::string name;
std::cout << "Enter a name: "
std::cin >> name;
board.setPlayer(Player(name));
std::cout << std::endl;
std::cout << "Enter a name: "
std::cin >> name;
board.setPlayer(Player(name));
std::cout << std::endl;
std::cout << "Enter a name: "
std::cin >> name;
board.setPlayer(Player(name));
gameboard.h
template<class T, class J, const int X, const int Y>
class Gameboard {
std::vector<J> players;
public:
void setPlayer(J player);
};
template<class T, class J, const int X, const int Y>
void Gameboard<T,J,X,Y>::setPlayer(J p) {
////// DEBUG CODE //////
std::cout << p.getName() << std::endl;
players.push_back(p);
for (int i = 0; i < players.size(); i++) {
std::cout << players.at(i).getName() << std::endl;
}
}
player.h/player.cpp
class Player {
std::string name;
public:
Player(std::string _name);
std::string getName();
};
Player::Player(std::string _name) {
name = _name;
}
std::string Player::getName() {
return name;
}
I think I've tracked my problem down to the code marked DEBUG CODE. Using the above code, and entering the names Bob, Joe, and Tim, I would get the following output:
Enter a name: bob
bob
Enter a name: joe
joe
Enter a name: tim
tim
[exit]
So somehow, when I add the player to the vector, it becomes corrupted or something similar. The object is valid right before insertion because I echo out the name. The vector is also growing in size because it's printing blank lines equal to the number of players added.
What is going on?

You might have a copy constructor where you are not copying the name. So when you push_back on the vector, a Player object with empty name gets pushed on the vector.
Implement the copy constructor properly and it should work

Related

I'm trying to figure out in issue in a simple line of coding [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last year.
Improve this question
#include <iostream>
#include <vector>
#include <ctime>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
string bob;
string alice;
string name;
for (int i = 0; i < 1; i++) {
cout << "Please enter the name bob or alice ";
cin >> name;
}
if (name == alice && name == bob) {
cout << " Greetings " << name;
}
else {
cout << "This name is invalid try again." << endl;
}
return 0;
}
Hello, I understand that this may be an unimportant or irrelevant topic, but I have a review test coming up in my computer science class. I'm trying to get a quick refresher in all that I've learned in last semester and I'm curious to why in this line of code when you type in bob or alice it should come out saying Greetings alice, or Greeting bob which ever you have inputted. Though right now it's completely skipping it and going to invalid try again. It's almost as if the information is being completely bypassed and then the code coming to a conclusion that nothing has been inputted.
Again I'm extremely sorry for the stupid question I'm just looking for a refresher.
Initialize your strings and change the && which is a Logical AND to a Logical OR ||
Also it would be better to void using namespace std;, more here .
Also there is no point in looping where you looped,because name will hold only the last input. Below the code I added maybe a case you wanted to catch,which loops some inputs and Greets Bob or Alice if found.
int main()
{
std::string bob = "Bob";
std::string alice = "Alice";
std::string name;
std::cout << "Please enter the name bob or alice ";
std::cin >> name;
if (name == alice || name == bob) {
std::cout << " Greetings " << name;
}
else {
std::cout << "This name is invalid try again." << endl;
}
return 0;
}
Perhaps what you wanted to do with your loop?
int main()
{
const std::string bob = "Bob"; //This will not change and DOESN'T need to change during runtime,so we make it const (same as alice below)
const std::string alice = "Alice";
std::string name; //This WILL change in fact in runtime,because we take input here right? So we don;t make it const
for(int i = 0 ; i < 1 ; ++i){
std::cout << "Please enter the name bob or alice " << std::endl;
std::cin >> name;
if (name == alice || name == bob) {
std::cout << " Greetings " << name << std::endl;
}
else {
std::cout << "This name is invalid try again." << std::endl;
}
}
return 0;
}
Reading suggestion as stated in comments : const

Where did i go wrong c++ classes [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
Hi this is my first subject (question) at stack overflow i've tried an project about c++ classes at Code::Blocks but something went wrong
#include <iostream>
using namespace std;
class char1
{
public:
string charName;
float charLength;
void printName()
{
cout<<"char name is"<<charName;
}
};
int main()
{
int charNAME;
float charLENGTH;
cout<<"write your char's name"<<endl;
cin>>charNAME;
cout<<"write your char's length"<<endl;
cin>>charLENGTH;
char1 name;
char1 length;
name.charName=charNAME;
length.charLength=charLENGTH;
return 0;
}
when i run program it asks me char's name i write something, after it asks char's length
but program end there i cant do anything
here is picture for help
Some fixes for your code to show you how to use your class in practice (with some
c++ coding tips).
#include <string>
#include <iostream>
// using namespace std; <== don't do this
// https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice
//class char1
class Character // <== give classes clear names, makes code more readable
{
public:
std::string name;
float length;
// I understand you want to do this to test stuff.
// but from a design point of view printing is not something
// a character can do to himself
/*
void printName()
{
cout << "char name is" << charName;
}
*/
};
// bit offtopic but :
// if you want to add support for printing your character
// its more common to overload operator<< for streams like this
std::ostream& operator<<(std::ostream& os, const Character& character)
{
os << "Your character's name = " << character.name << ", and his/her length = " << character.length << "\n";
return os;
}
int main()
{
// int charNAME; in your class this is a string, be consistent.
// float charLENGTH;
// make an instance of the Character class
Character character;
std::cout << "Enter your char's name : "; // << endl; avoid using endl use "\n" if you want a newline
std::cin >> character.name;
std::cout << "Enter your char's length : "; // << endl;
std::cin >> character.length;
std::cout << "\n";
std::cout << character; // this will now call your overloaded << operator
return 0;
}

How do I change my classes private attribute value? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
If I use a setter, it should then change my private classes attribute's value right? However that's not the case, it's just giving me the default value of the private attribute when I use the setter. I am finding the distance travelled value with a getter.
Player.h
#pragma once
class Player
{
public:
void setForestDistanceTravelled(int amount);
int getForestDistanceTravelled();
private:
unsigned short int forestDistanceTravelled = 0;
};
Player.cpp
#include "Player.h"
void Player::setForestDistanceTravelled(int amount)
{
forestDistanceTravelled += amount;
}
int Player::getForestDistanceTravelled()
{
return forestDistanceTravelled;
}
forest.cpp
void welcomeToForest()
{
Forest forest;
Player player;
std::string userInput;
system("cls");
std::cout << "Your current distance is: " << player.getForestDistanceTravelled();
std::cin >> userInput;
if (userInput == "1")
{
unsigned short int playerDist = 0;
system("cls");
playerDist = forestDistanceRand();
player.setForestDistanceTravelled(playerDist);
welcomeToForest();
}
}
As Yksisarvinen states in the comments, the problem lays in new instances of the Player object spawning again and again with each recursion of welcomeToForest().
You just want to isolate the recursive bit of that function into its own function, that accepts the Player object as an outside parameter.
Something like below should work, whilst preserving the recursive logic of the program:
void recursiveBit(Player& player_)
{
std::string userInput;
system("cls");
std::cout << "Your current distance is: "
<< player.getForestDistanceTravelled();
std::cin >> userInput;
if (userInput == "1")
{
unsigned short int playerDist = 0;
system("cls");
playerDist = forestDistanceRand();
player_.setForestDistanceTravelled(playerDist);
recursiveBit(player_);
}
}
void welcomeToForest()
{
Forest forest;
Player player;
recursiveBit(player);
}

Why can't I use push_back function? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
void Add(vector< vector<string> > &name,
vector< vector<string> > &author,
vector< vector<string> > &pub,
int &total_books)
{
Line();
string book_name,book_author,book_pub;
cout << "Please enter the book name: ";
cin >> book_name;
cout << "Please enter the author name: ";
cin >> book_author;
cout << "Please enter the publisher name: ";
cin >> book_pub;
name.push_back(book_name);
author.push_back(book_author);
pub.push_back(book_pub);
++total_books;
cout << "The book has been successfully added.";
}
Compiler says this:
[Error] no matching function for call to
'std::vector<std::vector<std::basic_string<char> >>::push_back(std::string&)'**
Does anybody know what's the problem?
With a std::vector<std::vector<string> >, you need to push_back an instance of std::vector<string>.
Example:
std::vector<string> many_strings;
std::vector<std::vector<string> > matrix_of_strings;
many_strings.push_back("Sid");
many_strings.push_back("Alice");
many_strings.push_back("Bob");
matrix_of_strings.push_back(many_strings);
In your case, a better solution is to make a structure with the fields rather than using parallel vectors.
struct Book
{
std::string title;
std::string author;
std::string publisher;
};
You can then add an input function:
struct Book
{
//...
void input_from_user();
};
void Book::input_from_user()
{
std::cout << "Enter book title: ";
std::getline(title);
std::cout << "Enter book author: ";
std::getline(author);
std::cout << "Enter book publisher: ";
std::getinle(publisher);
}
Your input process could look like this:
Book b;
b.input_from_user();
Your database would look like this:
std::vector<Book> database;
database.push_back(b);
Your variables are vectors of vectors (vector<vector<string> > &name), which seems to be one level to deep - you cannot push_back a string into those, but only a vector of strings.
What are you trying to accomplish with this? Why not simply use vector<string> &name, which should work just fine?
Sure, you're trying to push a string into a vector of vectors.
First, why are those vectors two-storeyed? If you change them into vector<string> no other changes will be needed (in this fragment.)
void Add(vector<string> &name, vector<string> &author, vector<string> &pub);
Next, if, due to some reason you still need them to be double level, well, you can insert fresh strings as singletons:
name.push_back({book_name});
(may need more verbosity in older standard:
author.push_back(vector<string>(1, book_author));
or add them to vector's most recent element:
pub.back().push_back(book_pub);
Perhaps, in the latter case you first need to check if the large vector is not empty, so there's a back().
It is unclear from your snippet what you're trying to achieve.

Whenever i use cin and use spaces in the string, why does it just skip through the whole thing? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I made a program that should take input print it. Then run a simple addition thing but when i use spaces in the input it skips through the addition. I do not know what the problem is.
this is the class stuff
#include <iostream>
#include <string>
using namespace std;
class Cheese {
private:
string name;
public:
void setName(string x){
cin >> x;
x = name;
}
string getName(){
return name;
}
void print(){
cout << name << endl;
}
};
this is the main stuff
int main()
{
string h;
Cheese hole;
hole.setName(h);
hole.getName();
hole.print();
this part is getting skipped through without letting me input
int x = 5;
int y = 16;
cout << x+y;
num(x);
int a;
int b;
int c;
cout << "Type in a number and press enter.";
cin >> a;
cout << "Repeat.";
cin >> b;
c = a+b;
cout << c << endl;
if(c <= 21){
cout << "Good job!";
}
else {
cout << "You fail!";
}
return 0;
}
I suggest you divide the responsibilities a little differently. The Cheese class's setName function should simply take a string and set the instance's member variable to the given argument.
Then your program can read from standard input and populate a string within main, and pass that string to setName.
To be more concrete:
class Cheese {
private:
string name;
public:
void setName(const string& x){
// change this code to set the 'name' member variable
}
[...]
};
And the main becomes:
int main()
{
string h;
Cheese hole;
std::string input_name;
cout << "Type a name and press enter.";
cin >> input_name; // Will read up to first whitespace character.
hole.setName(input_name);
hole.getName(); // this is a no-op: compiler may warn of unused return value
hole.print();
In general, reading standard input as part of a class's interface is a bad idea, because it makes it hard to re-use that class in the future (for example, with programs that take input from a file instead of from a human at a console).
The input that you pass to cin input stream skips any white space, Tab space or newline. If you wish to input string then you can use cin.getline(string s). The input after the white space gets passed to next waiting cin, as the next cin accepts integer and it get a character string it skips that. Thus when enter a string with white spaces the program skips the remaining part.