Struggling with pointers to Assign new contents to a vector - c++

Okay so what I am trying to do is add an instance of a class to a specific index of a vector. This index can either be initially non-existent, or be an existing index which has been cleared and is having a new class instance being written to that position.
Below is the function that I have been using to try and write these instances to the vector, and commented at the bottom you can see the other 2 methods that I tried to use, Obviously with push_back only being able to add new vectors at the end.
I have a feeling that assign may only be able to add data to existing elements? And that insert may add a new element and shift the existing elements down instead of overwriting. Just want a bit of clarity on this, as the C++ tutorials have started confusing me.
Also, what would be the correct way to reference/defreference/call the Person vector (in this case being referred to as "allthePeople"), so that it is possible to change its data?
void createnewPerson(int assignID, RECT startingpoint, vector<Person>* allthePeople, int framenumber) {
Person newguy(assignID, startingpoint, framenumber);
std::cout << "New Person ID number: " << newguy.getIDnumber() << std::endl;
std::cout << "New Person Recent Frame: " << newguy.getlastframeseen() << std::endl;
std::cout << "New Person Recent history bottom: " << newguy.getrecenthistory().bottom << std::endl;
int place = assignID - 1;
//This is where I am confused about referencing/dereferencing
allthePeople->assign(allthePeople->begin() + place, newguy);
//allthePeople->insert(place, newguy);
//allthePeople->push_back(newguy);
}
Also just to clarify, "place" is always 1 less than "assignID", because vector positions start at 0, and I simply wanted to start their ID numbers at 1 instead of 0.
-------------EDIT : ADDED IF LOOP THAT SOLVED PROBLEM-----------------
void createnewPerson(int assignID, RECT startingpoint, vector<Person>* allthePeople, int framenumber) {
Person newguy(assignID, startingpoint, framenumber);
std::cout << "New Person ID number: " << newguy.getIDnumber() << std::endl;
std::cout << "New Person Recent Frame: " << newguy.getlastframeseen() << std::endl;
std::cout << "New Person Recent history bottom: " << newguy.getrecenthistory().bottom << std::endl;
int place = assignID - 1;
if (allthePeople->size() > place)
{
//assuming places starts from 1 to vector's size.
(*allthePeople)[place] = newguy;
}
else
{
allthePeople->push_back(newguy);
}
}

assign is meant to replace the full content of a vector.
Assuming that you want to put every person in a specific place. You might then better use operator[] to put the value at the place you want instead of using assign. You need to have the vector with the appropriate size.
if (allthePeople->size() >= place )
{
//assuming places starts from 1 to vector's size.
(*allthePeople)[place - 1] = newguy;
}

Related

My recursive display function is not going to the next value of the array

I have a recursive display function, meant to go through the values of array b and print the details. My function is successful in looping the correct amount of times, but only prints out the value at index 0. For example, if I have 3 books, it prints out the first book 3 times and is not going to the other values. I am a beginner programmer and I believe I am missing something very simple or obvious, but any help is appreciated.
void displayBooks(int n)
{
// Write the code below
if (n >= currentCount) {
return;
}
else {
cout << "Name: " << b->getName() << "\n";
cout << "Name of Book Author: " << b->getAuthor() << "\n";
cout << "Publication Year: " << b->getYearOfPublication() << "\n";
cout << "ID: " << b->getID() << "\n";
displayBooks(n + 1);
}
}
This is the function itself, however I can't show the complete program since it is a lot of code with multiple files. When the function is first called as displayBooks(0) in a switch case.
I believe that you are not printing out each index of the "b" variable you need to access the index of each one. You need to have b as an array of pointers then access the index of that variable like b[n]->someProperty();
You can create the array like this:
Obj* b[HOWMANY];

How do I check whether an index of array is empty and then, if it is, skip to the next?

I'm trying to build a program that can register a user to the database (still learning cpp, I hope that in the near future I'll be able to work with database).
What I'm trying to do with this code is to check whether an index of array is empty for the user to store an ID in it. If it isn't empty, I want the program to keep looking for an empty index of array, for the new info to be stored in.
Here is the code:
void registro() {
std::string userid[3];
userid[0] = "Houkros"; // eventually I'll try to have this being read from a file or server database..
std::string userpass[3];
std::string usermail[3];
std::string userkey[3];
std::string getUid[3];
std::string getUpass[3];
std::string getUmail[3];
std::string getUkey[3];
std::cout << std::endl << " >>>> REGISTRATION <<<< " << std::endl;
std::cout << " =============================================== " << std::endl;
std::cout << std::endl;
std::cout << "Please, enter the desired user id: " << std::flush;
if (userid[0].empty())
{
std::cin >> userid[0];
}
else {
std::cin >> userid[1];
}
for (int i = 0; i < 2; i++)
{
std::cout << " Element of array: " << i << " is > " << userid[i] << std::endl;
}
Please consider the following definitions for an "empty" array element:
a) not initialised (unhelpful, cannot be checked)
b) never yet written to (same as a) )
c) contains "" (possible, but means that "" must not be accepted as an actual content)
d) is empty according to a second array in which that info is maintained (this is what I almost recommend)
e) contains a struct with a string and a maintained "empty" flag (this I recommend)
Whatever you do, make sure that you init all variables and array elements before first read-accessing them; i.e. in all cases first write something meaningful to it.

storing an object name during construction of another object

I wanted to create objects from the class “takeSnapshots” that would learn, upon their instantiation, the name of another object from the class “lock” that they could query later as the state of the “lock” object changes. I can think of multiple ways of letting the object from class “takeSnapshots” know which object it is to query (like including the name of the “lock” object as part of the call to its member functions). But, I thought it better to take care of the relation in the beginning and not worry later if I am calling the correct object combinations.
The included code shows stripped down versions of the two classes and example instantiations created in main.
I have included the outputs on each line following their respective couts.
What I expected was that the constructor of “takeSnapshots” would store away the address of the “lock” object. Then I could use it later when taking a snapshot. You can see that what gets stored away (at least when I use it to get numWheels) is a few addresses off from the address that the “lock” object thinks it has for numWheels.
I am mostly interested in knowing why this code does not work the way I expect, i.e, if this is not a good architectural idea, that is one thing. But with the behavior I’m seeing here, I’m clearly not ready to use pointers in anything complicated and I don’t want to give up on the basic architecture just because of erroneous implementation. Any help would be greatly appreciated.
// simpleTest.cpp : Demonstrates problem I'm having understanding
// pointer to an object.
#include "stdafx.h"
#include<iostream>
using namespace std;
class lock {
public: //Just while I run a test.
int numWheels;
lock(int numW) {
numWheels = numW;
cout << " \n In \"lock\" constuctor, address and value of numWheels
" << &numWheels << " " << numWheels << endl;
} //Values from console: 0034F874 and 4
};
class takeSnapshots {
lock* localLock;
public:
takeSnapshots(lock myLock) {
localLock = &myLock;
cout << " \n In \"takeSnapshots\" constuctor, address and value of
numWheels " << &localLock->numWheels << " "
<< localLock->numWheels << endl;
//Values from console: 0034F794 and 4 "Same value, but not the same
//address as expected from "lock."
}
void takeASnapSnapshot() {
cout << " \n When taking a snapshot, address and value of numWheels
" << &localLock->numWheels << " " << localLock->numWheels <<
endl;
//Values from console: 0034F794 and 2303449 "No longer even the
// same value as expected from "lock."
}
};
int main()
{
lock yourLock(4);
takeSnapshots myShots1(yourLock);
cout << " \n In main (from \"yourLock\"), address and value of
numWheels " << &yourLock.numWheels << " " << yourLock.numWheels <<
endl;
//Values from console: 0034F874 and 4 "Still the same values as set
//in the constructor of "lock."
//Take a picture
myShots1.takeASnapSnapshot();
return 0;
}

C++ Structs in arrays

Am i doing this right, I want a map with a Integer as key, and struct as value. What is the easiest way to, say I want the object at 1. How do I retrieve the value of isIncluded? The last two lines in the code, I tried doing it, but then I realized I don´t really know what is the way to retrieving values of structs in a numbered Map array.
Do I need to call cells.get(1) and assign that to a new temporarely struct to get its values?
/** set ups cells map. with initial state of all cells and their info*/
void setExcludedCells (int dimension)
{
// Sets initial state for cells
cellInfo getCellInfo;
getCellInfo.isIncluded = false;
getCellInfo.north = 0;
getCellInfo.south = 0;
getCellInfo.west = 0;
getCellInfo.east = 0;
for (int i = 1; i <= (pow(dimension, 2)); i++)
{
cells.put(i, getCellInfo);
}
cout << "Cells map initialized. Set [" << + cells.size() << "] cells to excluded: " << endl;
cells.get(getCellInfo.isIncluded);
cells.get(1);
}
the Map, is declared as an private instance variable like this:
struct cellInfo {
bool isIncluded;
int north; // If value is 0, that direction is not applicable (border of grid).
int south;
int west;
int east;
};
Map<int, cellInfo> cells; // Keeps track over included /excluded cells
From the documentation for Map, it appears that .get() returns a ValueType.
You would use it thus:
// Display item #1
std::cout << cells.get(1).isIncluded << "\n";
std::cout << cells.get(1).north << "\n";
Or, since the lookup is relatively expensive, you could copy it to a local variable:
// Display item #1 via initialized local variable
cellInfo ci = cells.get(1);
std::cout << ci.isIncluded << " " << ci.north << "\n";
// Display item #2 via assigned-to local variable
ci = cells.get(2);
std::cout << ci.isIncluded << " " << ci.north << "\n";
My best advice is to use the standard library's std::map data structure instead:
// Expensive way with multiple lookups:
std::cout << cells[1].isIncluded << " " << cells[1].north << "\n";
// Cheap way with one lookup and no copies
const cellinfo& ci(maps[1]);
std::cout << ci.isIncluded << " " << ci.north << "\n";

multimap iterator not working

I have a Playlist class that has a vector with Tracks and each Track has a multimap<long, Note> as datamember.
class Track {
private:
multimap<long, Note> noteList;
}
Using an iterator to acces the tracks is no problem, so this part here is working fine:
vector<Track>::iterator trackIT;
try{
for(noteIT = trackIT->getNoteList().begin(); noteIT != trackIT->getNoteList().end(); noteIT++){
cout << "---" << noteIT->second.getName() << endl;
}
}catch (int e){
cout << "exception #" << e << endl;
}
What I want to do next is iterate the Notes of each Track. But starting from this part all output is stopped. So I only get to see the first tracks name. Any cout's after that are not shown and the compiler isn't giving me any errors. Even the cout inside the try catch block isn't working..
vector<Track>::iterator trackIT;
multimap<long, Note>::iterator noteIT;
for(trackIT = this->playlist.getTracklist().begin(); trackIT < this->playlist.getTracklist().end(); trackIT++){
cout << trackIT->getTrackName() << endl;
for(noteIT = trackIT->getNoteList().begin(); noteIT != trackIT->getNoteList().end(); noteIT++){
cout << "---" << noteIT->second.getName() << endl;
}
}
cout << "random cout that is NOT shown" << endl; // this part doesn't show up in console either
Also, the method in my Track class that I'm using to add the Note objects looks like this:
void Track::addNote(Note &note) {
long key = 1000009;
this->noteList.insert(make_pair(key, note));
}
// I'm adding the notes to the track like this:
Note note1(440, 100, 8, 1, 1);
note1.setName("note1");
synthTrack.addNote(note1);
Any ideas why the iterator won't work?
Change
noteIT < trackIT->getNoteList().end()
To
noteIT != trackIT->getNoteList().end()
Not all iterators support less than / greater than comparisons.
If you have c++11 you can use a range-based for loop:
for (Note& note : trackIT->getNoteList())
Or you can use BOOST_FOREACH
BOOST_FOREACH (Note& note, trackIT->getNoteList())
You haven't shown the definitions of getTrackList or getNoteList, but there's a common mistake people make - if you return a copy of the container instead of a reference to it, the iterators will be pointing to different containers making comparisons impossible. Not only that but since the containers are temporary any use of the iterators results in undefined behavior.
If you are really hardcoding the track key, then there will only ever be one track in the map because std::map stores unique keys...
long key = 1000009; //If yo are really doing this, this key is already inserted so it will fail to insert more.
Also, if you would like a more elegant approach you could use function object.
struct print_track
{
void operator()(const Track& track)
{
cout << track.getTrackName() << endl;
std::for_each(track.getNoteList().begin(), track.getNoteList().end(), print_track_name());
}
};
struct print_note_name
{
void operator()(const std::pair<long,Note>& note_pair)
{
cout << "---" << note_pair.second.getName() << endl;
}
};
//In use...
std::for_each(playlist.getTracklist().begin(), playlist.getTracklist.end(), print_track());