C++: Loop will run at most once (loop increment never executed) - c++

I know there is a topic Loop will run at most once (loop increment never executed), but it does not answear my question.
I have following code:
class Station{
public:
Station();
void addWartezimmer(Wartezimmer wartezimmer);
void addBehandlungszimmer(Behandlungszimmer behandlungszimmer);
int getWartezimmer();
private:
list<Wartezimmer> WartezimmerListe;
list<Behandlungszimmer> BehandlungszimmerListe;
};
Station::Station(){
}
void Station::addWartezimmer(Wartezimmer wartezimmer){
this->WartezimmerListe.push_back(wartezimmer);
}
void Station::addBehandlungszimmer(Behandlungszimmer behandlungszimmer){
this->BehandlungszimmerListe.push_back(behandlungszimmer);
}
int Station::getWartezimmer(){
list<Wartezimmer>::iterator i;
for (i = WartezimmerListe.begin(); i != WartezimmerListe.end(); i++){
return i->getAnzahlPlaetze();
}
return 0;
};
int main(int argc, const char * argv[]) {
Zimmer zimmer("05.23");
Wartezimmer WarteZimmer1(12, "01.12");
Wartezimmer WarteZimmer2(14, "03.12");
Behandlungszimmer Behandlungszimmer1("Intensiv", "01.01");
Station West;
West.addWartezimmer(WarteZimmer1);
West.addWartezimmer(WarteZimmer2);
West.addBehandlungszimmer(Behandlungszimmer1);
cout << West.getWartezimmer();
}
If I execute this command, it will be printed "12". I expect "1214", because there are two Objects which have Numbers.
If I change the function to void and print it in the function, it is "1214".
void Station::getWartezimmer(){
list<Wartezimmer>::iterator i;
for (i = WartezimmerListe.begin(); i != WartezimmerListe.end(); i++){
cout << i->getAnzahlPlaetze();
}
};
So my specific Question: How can I return a value of a function, if it is more than one value from a list? I don´t want only "12", I want "1214" because they are 2 Objects.

If you would like to get whole data you could change int getWartezimmer(); to
list<Wartezimmer> Station::getWartezimmer()
{
return WartezimmerListe;
}
but I guess you want AnzahlPlaetze whatever it is so int getWartezimmer you could simply do this
vector<AnzahlPlaetze> Station::getWartezimmer()
{
vector<AnzahlPlaetze> result;
for(const auto& ob: WartezimmerListe)
{
result.push_back(ob.getAnzahlPlaetze());
}
return result
}

Your code is working exactly as it should work, the function getWartezimmer() returns something as soon as it finds it.
In this code
int Station::getWartezimmer(){
list<Wartezimmer>::iterator I;
for (i = WartezimmerListe.begin(); i != WartezimmerListe.end(); i++){
return i->getAnzahlPlaetze(); //--> this line
}
return 0;
};
at the lined I've marked, the function getAnzahlPlaetze() fetches a value and returns it to a returns statement. What happens then? the return statement returns this value to the main function and the execution continues from there. So every time you call this function, it will always return the firs value of the WartezimmerListe vector.
I don't know the exact behavior that you are looking for after calling getWartezimmer(). do you wanna pop an element from the beginning of the array or from its end?
You can edit the getAnzahlPlaetze() function to return an element and then delete it or use std::vector::pop_back() if it matches your needs. This will effectively give you a new value for each call.
If you want to maintain the original vector but also poping values from it you can define a static variable inside the class and use it to index the vector.
I don't think you want getAnzahlPlaetze() to return the whole values of the vector because it makes no sense. You can use the vector itself.

Related

How would I print the index of an array? C++

I was just wondering how do I print off the Index position of an array? I know there's an if loop involved but I just can't seem to understand it properly.
I want the code to be able to print off what the element of the Array is and the position number. I should also mention that this is for a function as well. Any help will be appreciated. Below is my code
int index_of(string names[], int size)
{
string name;
int index;
for(int i = 0; i < size; i++)
{
if (to_lowercase (names[i]) == to_lowercase(name));
{
return;
}
}
}
What you are trying to do is called "searching".
You have a string which (potentially) is the known content of an entry in an array, but at an unknown index.
What you need to do is to find the index which, used for accessing the entry at that index, yields content which is identical to what you are looking for.
The code you show is more or less pseudo code for doing exactly that.
However, the shown code will not work for the following reasons:
it does not correctly return the index in question, it should return i;
it only returns explicitly in case of finding something, it should, after the loop, return -1;(as a proposal how to communicate failure)
it incorrectly compares (the == operator cannot meaningfully be used on "strings", which in C are only pointers to characters), it should use strncmp(), see e.g. https://en.cppreference.com/w/c/string/byte/strncmp
it does not actually print anything, but I think that is a problem of phrasing your goal and you can easily add a print outside of the shown code, using the (now hopefully correct and correctly returned) return value of the shown function
it has the problem mentioned by Nathan Pierson, see their comment/answer
This is what managed to print the indexes, you guys were actually able to help me understand what I was doing
int index_of(string names[], int size, string name)
{
for(int i = 0; i < size; i++)
{
if (to_lowercase (names[i]) == to_lowercase(name));
{
return i;
}
return -1;
}
}

Cannot dereference double pointer, " no match for operator* "

I'm trying to search through an array of pointers to objects of class Shape. I have written the following code. However, I'm getting this error: "no match for operator*", and I don't know where to go from here. Any help is appreciated.
Shape** shapesArray;
bool doesNameExist(string name) {
for (int i = 0; i < shapeCount; i++)
{
if(*(shapesArray[i])->getName() == name)
{
return true;
}
else
{
return false;
}
}
}
shapesArray is a Shape**
shapesArray[i] is Shape*
(shapesArray[i])->getName() is dereferencing shapesArray[i] and calls its
member getName
So far nothing wrong. I guess this is what you actually want to get, but you add another *:
*(shapesArray[i])->getName() tries to dereference what was returned from getName (a std::string perhaps?)
PS: You return from the loop in the first iteration in either case. If you want to search in the array you need to loop until you find it (then return true) or loop till the end (then return false after the loop, because it wasn't found).

Dynamic Programming, Traversal Method

int fib(int numb){
vector<int> temp;
int str;
if(numb==0 || numb==1){
return numb;
}
else{
str=(fib(numb-1)+fib(numb-2));
temp.push_back(str);
return str;
}
for(int i=0;i<temp.size();i++){
if(temp[i]==numb){
return temp[i];
}}
Fibonacci function and it work but how do I check if the for loop part of the function really works? Its for a traversal method of finding a existing number and returning it instead of processing another recursion.
Your loop can't possibly work. It will never work. Because there's no way to get to the loop. Every code path before the loop ends with a return statement.
Walk through your code, statement by statement, and see for yourself that your code will never reach the loop.
You must process the stored elements before returning any value. More, as you store elements in vector during recursive calls, the vector temp must be static.
And the research should not be that: you should store in the vector the values, said differently, what you want it temp[i] is fib(i).
A simple way to do that is to make use that C++ allows initializing of static values through functions. You could then initialize temp to { 0, 1}, and when asked for a value, just look if the number is higher than temp.size:
if it is, compute it and store it into temp - as you compute them with values of fib(n-1) and fib(n-2), when you compute it you know that the temp vector already contains fib(n-1), and does not still contains fib(n) => you have just to push it back into temp
it not just extract it from temp
Code could be:
// return a temporary vector containing 0 and 1
std::vector<int> inifib() {
std::vector<int> t;
t.push_back(0);
t.push_back(1);
return t;
}
int fib(unsigned int numb) {
static std::vector<int> temp = inifib(); // initialize once the static temp with size 2 and values 0,1
if (numb >= temp.size()) {
int cr = fib(numb-1) + fib(numb - 2);
temp.push_back(cr); // when we are here, temp contains everything up to fib(numb - 1) - just push
}
return temp[numb];
}

C++ Function will not execute more than once

I've tried looking around but I can't find anything about this anywhere.
I'm writing a custom array class with a "push" function to add a value to the array.
It seems to work perfectly fine but won't execute more than once.
Take the main method below for example:
int main()
{
Array<int> test(4,5);
test.push(4);
test.writeOrdered("Output.txt");
return 0;
}
This will put the int value 4 into the array at the first available position and execute the writeOrdered function.
The following main method, on the other hand:
int main()
{
Array<int> test(4,5);
test.push(4);
test.push(5);
test.writeOrdered("Output.txt");
return 0;
}
This will put the number 4 into the array at the first available point as above and then stop. It won't execute any further lines of code.
Here's the push function for reference:
void push(Datatype p_item)
{
bool inserted = false;
int i = 0;
while (inserted == false)
{
if (m_array[i] < 0)
{
m_array[i] = p_item;
i++;
inserted = true;
cout << p_item << " saved to array" << endl;
system("pause");
}
}
}
You have an infinite loop. After the first insert m_array[0] >= 0 and i never grows. You would have found it out, had you debugged the code somehow.
Basically I don't understand your push function but the way it is, after you insert a non-negative value into the first position any further call to your push function results in a tight loop.
I imagine that you want the i++ outside the if statement.
Without seeing the full implementation of the Array class I would guess that the array m_array contains negative numbers by default. This will allow the first call to the push method to succeed. The next call to the method contains a value of 4 at index 0 and will be stuck in an infinite loop because inserted will never be set to true nor will the value of i be incremented.

Array setup in constructor means failure later on

I had an issue where my code segfaulted on attempting to use the size() function of a list. On the advice of stackoverflow :-) I constructed a minimum case in which the segfault occurs (on the call inventory.size() below). It is:
#include <list>
class Thing {};
class Player {
private:
int xpCalcArray[99];
std::list<Thing*> inventory;
public:
Player();
int addToInv(Thing& t); // return 1 on success, 0 on failure
};
Player::Player() {
// set up XP calculation array
for (int i=1; i<100; i++) {
if (i<=10) {
xpCalcArray[i] = i*100;
}
if (i>10 && i<=50) {
xpCalcArray[i] = i*1000;
}
if (i>50 && i<=99) {
xpCalcArray[i] = i*5000;
}
}
}
int Player::addToInv(Thing& t) {
if (inventory.size() == 52) {
return 0;
} else {
inventory.push_back(&t);
}
return 1;
}
int main(int argc, char *argv[]) {
Thing t;
Player pc;
pc.addToInv(t);
return 1;
}
I notice that when I remove the setting up of the array in the Player cosntructor, it works fine, so this looks to be the problem. What am I doing wrong?
You are accessing your array out of bounds, which results in undefined behaviour. The valid index range for this array
int xpCalcArray[99];
is 0 to 98. You are accessing index 99 here:
if (i>50 && i<=99) {
xpCalcArray[i] = i*5000;
}
Your outer loop should be
for (int i=0; i<99; i++) { ... }
Note I start from 0, although it is an assumption that you actually want to access the first element.
Then your final condition can be simplified to
if (i>50) {
xpCalcArray[i] = i*5000;
}
If you intended to use a size 100 array, then you need
int xpCalcArray[100];
then loop between int i=0; i<100;.
You are accessing outside the bounds of your array. Doing so causes undefined behaviour and so there is no logical explanation for anything that occurs afterwards. The size of your array is 99 and so the last index is 98. Your for loop goes up to 99, however.
Either make your array size 100:
int xpCalcArray[100];
Or change your for condition to i < 99.
You are overwriting your array of 99 ints by attempting to modify the 2nd→100th elements (rather than 1st→99th).
In your case, this happens to overwrite some memory within the std::list<Thing*> (which exists in memory directly after the array — not always, but evidently for you today) and thus, when you try to use the list, all hell breaks loose when its internal member data is no longer what it thought it was.
You xpCalcArray is defined from 0 up to 98 (being 99 elements large).
Your loop goes from 0 up to 99, taking 100 steps.
The last loop cycle, writes xpCalcArray at location 99, which does not exist. This (indirectly) results in your segmentation fault as shown by the answer of Lightness Races in Orbit.
So, increase the size of xpCalcArray by 1:
int xpCalcArray[100];