im new in c++ (and not to old in programming...) and i have problem with handling vectors and strucs in class.
basically i have a vector and a array of pointers to struct members in the class and i want work on the in my methos but im doing something worng/
here is my movement.h
#pragma once
using namespace std;
class movement
{
private:
static const int MAX_ROW_PER_TRACKER = 100;
static const int MIN_TO_START_CALC = 30;
static const int MAX_TRACKERS = 20;
struct tracker
{
int id;
double a[MAX_ROW_PER_TRACKER];
double b[MAX_ROW_PER_TRACKER];
double c;
};
vector<int> trackersOrder[MAX_TRACKERS] = {};
tracker* trackersArr[MAX_TRACKERS];
public:
movement();
void addRow(int a, int b, int c);
~movement();
};
and my movement.cpp
#include "stdafx.h"
#include "movement.h"
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
movement::movement()
{
}
void movement::addRow(int id, int a, int b)
{
int index;
vector<int>::iterator searchID = find(trackersOrder.begin(), trackersOrder.end(), ID);
if (searchID == trackersOrder.end())
{
vector<int>::iterator freeLocation = find(trackersOrder.begin(), trackersOrder.end(), 0);
index = freeLocation - trackersOrder.begin();
trackersOrder.insert(trackersOrder.begin + index, id);
structArr[index] = new tracker;
structArr[index]->id = id;
structArr[index]->a[0] = a;
structArr[index]->b[0] = b;
structArr[index]->c = 0;
}
}
movement::~movement()
{
}
so when i send to method "addRow" id, and b i want to first check if i allready have this id in my vector (the vector just give me the index for the structs array) and if not then if put the id in the first empty place in the vector and on the structs array/
but from some reasin its look to me that the methid dont reconized the vector and the structs. can you help me understand why?
p.s - i can bet that i have more mistakes in my code, its my firs try with pointers and ect. (im comming from the good life in Matlab) so i will be happy to learn on them also
thank you very much!
The main problem
The problem is that in your code, trackersOrder is not a vector but an array of vectors:
vector<int> trackersOrder[MAX_TRACKERS] = {}; // array of MAXTRACKERS vectors !!
The solution
If you define it as simple vector, it should work better:
vector<int> trackersOrder;
If you want to set its size do it in the movement constructor:
movement::movement() : trackersOrder(MAX_TRACKERS)
{
}
Other issues
There is a case typo with an ID that should be id.
auto searchID = find(trackersOrder.begin(), trackersOrder.end(), id); // by the way auto is easier + ID corrected
There are a missing () after a begin whicn transforms unfortunately your iterator arithmetic into function pointer arithmetic (sic!!):
trackersOrder.insert(trackersOrder.begin() + index, id); // corrected
Finally, there are a couple of structArr that should be replaced by trackersArr.
The result does finally compile (online demo)
Related
I am trying to create an array in my UnsortedList class. I specified to create an array in the header file, and I also specified the MAX_SIZE, which is equal to 10. However, whenever I create my object of the class, the default constructor does not create that array with the MAX_SIZE. I am unsure what I am doing wrong. I also get an error saying "stack around the variable 'myList' was corrupted". Also, just as a side note, can I initialize the array values when the default constructor is called, instead of creating a function to do it?
"UnsortedList.h" header file:
#pragma once
class UnsortedList {
public:
UnsortedList();
bool IsFull(); //Determines whether the list is full or not (returns T or F)
int GetLength(); //Gets the length of the list
void SetListValues();
private:
int length;
const int MAX_ITEMS = 10;
int numbers[];
};
"UnsortedList.cpp" file:
#pragma once
#include "UnsortedList.h"
#include <fstream>
#include <iostream>
using namespace std;
UnsortedList::UnsortedList() {
length = 0; //sets length to 0
numbers[MAX_ITEMS]; //sets array maximum size to MAX_ITEMS (10 as indicated in UnsortedList.h)
}
bool UnsortedList::IsFull() {
return (length == MAX_ITEMS);
}
int UnsortedList::GetLength() {
return length;
}
void UnsortedList::SetListValues() {
ifstream inFile;
inFile.open("values.txt");
int x = 0;
while (!inFile.eof()) {
inFile >> numbers[x];
x++;
}
}
"main.cpp" file:
#include <iostream>
#include <string>
#include "UnsortedList.h"
using namespace std;
int main() {
UnsortedList myList;
myList.SetListValues();
return 0;
}
I recommend you use std::array or std::vector, but if you must use C arrays, then your definition in the header needs correcting:
class UnsortedList {
// ...
const static int MAX_ITEMS = 10;
int numbers[MAX_ITEMS];
};
You can remove the corresponding line in the constructor. The file reading method also needs correcting:
void UnsortedList::SetListValues() {
ifstream inFile;
inFile.open("values.txt");
int x = 0;
int read_value;
// x < MAX_ITEMS to avoid out of bounds access
while (x != MAX_ITEMS && inFile >> read_value)
{
numbers[x++] = read_value;
length++; // I assume you also want to increment the length at this point?
}
}
Edit: As noted by #πάνταῥεῖ, there is no good reason to use C style arrays when the standard provides std::array. Not much changes, it is declared as:
std::array<int, MAX_ITEMS> numbers;
You can use operator[] as with the C array. This is preferable as it provides a richer API and can be used like other C++ containers, i.e. with STL algorithms.
I need to copy the contents of a std::list into an array, wherein the array is struct of array. Below is the code implementation of it.
#include <iostream>
#include <string>
using namespace std;
typedef struct
{
int height;
int width;
int length;
}dimensions;
GetDimensions(list<std::string>, *int); // Function that copies the content of list to array passed as second parameter
int main()
{
dimensions cuboid[10];
int plane[10];
list<std::string> planeList = GetList();//Function that returns list of elements
list<std::string> dimensionList = GetList();
GetDimensions(planeList,&plane);//This is fine, as it is a simple array
GetDimensions(dimensionList,&cuboid.height);//Trouble in implementation of this usecase, for cuboid.height, cuboid.width and cuboid.height.
return 0;
}
GetDimensions(list<std::string>dimensionList, int* dimensionParams)
{
int i=0;
for(list<std::string>::iterator it = dimensionList.begin(); it != dimensionList.end(); ++it)
{
dimensionParams[i] = stoi(*it);
i++;
}
}
Here, I need GetDimensions() function to copy the list (passed as first parameter) to array (second parameter). The implemented function works well for simple array plane. But how to pass the array of struct as parameter to the function ?
I will be getting the std::list as cuboid.height, cuboid.width and cuboid.length. So the function has to copy the contents of list from cuboid[0].height to cuboid[i].height respectively. Is there any specific function to copy the content directly?
Use std::array 's instead. Then your problem can be reduced to passing two different types of arrays to a single function.
This can be solved
either by good old function overloads
or in c++17 function template with
if-constexpr.
Following is an example code with templated function with if-constexpr (See live online)
#include <iostream>
#include <string>
#include <list>
#include <array>
#include <type_traits> // std::is_same_v
struct dimensions // no need to typedef here
{
int height;
int width;
int length;
};
template<typename T>
void GetDimensions(const list<std::string>& dimensionList, T& dimensionParams)
^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //---> pass list by const-ref as the values are non-modifying
{
int i{0};
if constexpr (std::is_same_v<std::array<int, 10>, T>)
{
for(const std::string& str: dimensionList) dimensionParams[i++] = std::stoi(str);
}
else
{
for(const std::string& str: dimensionList) dimensionParams[i++].height = std::stoi(str);
}
}
int main()
{
std::array<dimensions, 10> cuboid; // use std::array instead of VLA
std::array<int, 10> plane;
std::list<std::string> planeList{"1", "2"}; // some list
std::list<std::string> dimensionList{"1", "2"};
GetDimensions(planeList, plane);
GetDimensions(dimensionList, cuboid);
return 0;
}
Also note that:
You have not specified the return type of GetDimensions function.
You probably want to return void there.
in C++ you do not need to use typedef alias for struct { ... }.
last but not least, do not practice with using namespace std;
You can do this with boost::transform_iterator.
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <boost/iterator/transform_iterator.hpp>
struct dimensions {
int height;
int width;
int length;
};
template <typename OutputIt>
void GetDimensions(std::list<std::string> dimensionList, OutputIt dimensionParams)
{
// N.b. taking the address of a standard library function is undefined, so wrap in a lambda
auto stoi = [](std::string s){ return std::stoi(s); };
std::copy(boost::make_transform_iterator(dimensionList.begin(), stoi),
boost::make_transform_iterator(dimensionList.end(), stoi),
dimensionParams);
}
int main() {
dimensions cuboid[10];
int plane[10];
std::list<std::string> planeList = GetList();
std::list<std::string> heightList = GetList();
std::list<std::string> widthList = GetList();
std::list<std::string> lengthList = GetList();
GetDimensions(planeList, plane);
GetDimensions(heightList,
boost::make_transform_iterator(cuboid, std::mem_fn(&dimensions::height)));
GetDimensions(widthList,
boost::make_transform_iterator(cuboid, std::mem_fn(&dimensions::width)));
GetDimensions(lengthList,
boost::make_transform_iterator(cuboid, std::mem_fn(&dimensions::length)));
return 0;
}
I have to use a struct array called Robot_parts[] for each part_rect struct (part_num, part_name, part_quantity, part_cost)
And through the void display function, I have to display Robot_parts[] array entirely through pointer but I don't know how, and I don't know where to declare Robot_parts[] and whether i have to put any number value inside the brackets.
So far I have:
#include <iostream>
#include <string>
using namespace std;
void display();
struct part_rec
{
int part_num;
string part_name;
int part_quantity;
double part_cost;
};
int main()
{
part_rec Robot_parts[ ] = {
{7789, "QTI", 4, 12.95},
{1654, "bolt", 4, 0.34},
{6931, "nut", 4, 0.25}
};
return 0;
}
void display()
{
cout<<Robot_parts[]<<endl<<endl;
}
If I also made a few other errors, please let me know. Thanks!
As stated in a comment it would be much better to use a c++ container like a std::vector or std::array.
But since your professor requires an old-style array, you could try like the code below - see the comments for explanation:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct part_rec
{
int part_num;
string part_name;
int part_quantity;
double part_cost;
};
// You have to pass a pointer (to the array) and the size of the array
// to the display function
void display(part_rec* Robot_parts, int n);
// Make a function so that you can "cout" your class directly using <<
// Note: Thanks to #BaumMitAugen who provided this comment and link:
// It makes use of the so called Operator Overloading - see:
// https://stackoverflow.com/questions/4421706/operator-overloading
// The link is also below the code section
std::ostream &operator<<(std::ostream &os, part_rec const &m)
{
// Note - Only two members printed here - just add the rest your self
return os << m.part_num << " " << m.part_name;
}
int main()
{
part_rec Robot_parts[] {
{7789, "QTI", 4, 12.95},
{1654, "bolt", 4, 0.34},
{6931, "nut", 4, 0.25}
};
display(Robot_parts, 3);
return 0;
}
void display(part_rec* Robot_parts, int n)
{
// Loop over all instances of your class in the array
for (int i = 0; i < n; ++i)
{
// Print your class
cout << Robot_parts[i] << endl;
}
}
The link recommended by #BaumMitAugen:
Operator overloading
I want to declare a pointer in my .h and initialize it in .cpp. For example an int pointer:
My .h class file:
#pragma once
#include <iostream>
#include <stdio.h>
#include <stdint.h>
using namespace std;
class Calc_ToF_low
{
private:
int telo[3];
public:
Calc_ToF_low(void);
~Calc_ToF_low(void);
double * CalcToF(int16_t * señal, int fs);
long double * filter(long double *ganancias, long double *coeficientes, double *señal,int lensignal, int L, int control);
void signal_p1_lowf(void);
void avg_p1_lowf(void);
void time_est();
};
My .cpp class file:
#include "Calc_ToF_low.h"
Calc_ToF_low::Calc_ToF_low(void)
{
telo[3]={0,1,2};
}
How can I do this?
Like this:
Calc_ToF_low::Calc_ToF_low() // note no need to say void in C++
{
telo[0]=0;
telo[1]=1;
telo[2]=2;
}
Or if you can use C++11, something like this might work:
Calc_ToF_low::Calc_ToF_low()
: telo{{0,1,2}} // initializer list, will not work in "old" C++98
{}
You could just assign values to it by typing:
telo[0] = 0;
telo[1] = 1;
telo[2] = 2;
in your .cpp.
It may not be perfect for huge arrays but then you probably should assign the values from a file instead.
If you're initializing large arrays with a constant value for all item, you can use this approach:
Calc_ToF_low::Calc_ToF_low(){
memset(telo, 0, sizeof(telo)); //0 is the constant value
}
If you want to initialize your large array to some set of values that has no patterns:
int defaultTeloData[TELO_NUMITEM] = {2,4,1,5,6,1,7,82,41,6,134,88,1};
Calc_ToF_low::Calc_ToF_low(){
memcpy(telo, defaultTeloData, sizeof(telo));
}
If your array values has pattern, use a loop and some formulas or constructors.
Calc_ToF_low::Calc_ToF_low(){
for(int a = 0; a sizeof(telo)/sizeof(telo[0]); a++){
telo[a] = dataFormulaForTelo(a);
}
}
This is one way you could do it:
#include <array>
class Calc_ToF_low
{
private:
std::array<int, 3> telo;
public:
Calc_ToF_low();
};
Calc_ToF_low::Calc_ToF_low()
: telo()
{
for(unsigned i = 0; i<telo.size(); ++i)
telo[i] = i;
}
I'm trying to initialise static pointers as arrays inside a class definition, but getting runtime errors. I've seen examples where something similar is done, but I can't get it working, and not sure why. Some example code I've tried is:
class Header
{
private:
static int *pointer;
public:
int getVal(int val);
};
Class definition:
#include "Header.h"
int* Header::pointer = new int[] {0, 1, 2, 3, 4};
int Header::getVal(int val)
{
return pointer[val];
}
main:
#include "Header.h"
#include <iostream>
int main(int argc, char ** argv)
{
Header header;
for (int i = 0; i < 5; i++)
{
std::cout << header.getVal(i);
}
}
Running this causes an error while initialising the pointer. If I run through it in the debugger, and ignore the error, I can see that the pointer is initisalised with 0 at the beginning. If I then continue to step through it I get another error saying the heap's been corrupted. Is it possible to intitialise a pointer in this way? If not, are there any suggestions on how one can initialise a member variable pointer into an array, and assign it values, inside the class definition without having to assign each element of the array individually.
You could probably get away with:
class Header
{
public:
int getVal(int valIndex);
};
and then
#include "Header.h"
static int s_vals[] = {0, 1, 2, 3, 4}; // could move this line to B
int Header::getVal(int valIndex)
{
// B
return s_vals[valIndex];
}
Considering that you know the size of the array at compile time and there is no need to advertise an implementation detail if you are providing accessors anyway.
it is possible that your compiler simply does not support braced-init-list.
If so you can rewrite your class the following way
class Header
{
private:
static int *pointer;
static int *init()
{
int *p = new int[5];
std::iota( p, p + 5, 0 );
return ( p );
}
public:
int getVal(int val);
};
And then pointer is defined the following way
int * Header::pointer = Header::init();