Accessing pointer to a vector in a struct - c++

How can I access the value of a pointer to a vector in a struct? I've got the following code:
#include <iostream>
#include <vector>
using namespace std;
struct item {
int value;
vector<bool> pb;
vector<bool> *path = &pb;
};
int main(int argc, char* argv[]) {
vector<item> dp(10);
for (int n = 0; n < 10; n++)
dp[n].pb = vector<bool>(10);
if (dp[1].path[2] == true)
cout << "true";
else cout << "false";
}
Which results in the following compilation error:
Error C2678 binary '==': no operator found which takes a left-hand operand of type 'std::vector<bool,std::allocator<_Ty>>' (or there is no acceptable conversion)
How can I access the value stored at dp[1].path[2]?

path is a pointer to a vector. You have to do the following to access the value in the vector that it points to
if ((*(dp[1].path))[2] == true)
or
if (dp[1].path->operator[](2) == true)

In addition, you can use at function which is also
checks whether n is within the bounds of valid elements in the vector
code example
if (dp[1].path->at(2) == true)

Related

Returning Array in C++ returns unaccessable elements

I am working on a project where I parse a string in to an array and then return it back to the main function. It parses fine but when I return it to the main function I can't get access to the array elements.
//This is from the Main function. It calls commaSeparatedToArray which returns the array.
for (int i = 0; i < numberOfStudents; i++) {
string * parsedToArray = mainRoster->commaSeparatedToArray(studentData[i]);
Degree degreeType = SOFTWARE;
for (int i = 0; i < 3; i++) {
if (degreeTypeStrings[i] == parsedToArray[8])
degreeType = static_cast<Degree>(i);
}
mainRoster->add(parsedToArray[0], parsedToArray[1], parsedToArray[2], parsedToArray[3], stoi(parsedToArray[4]), stoi(parsedToArray[5]), stoi(parsedToArray[6]), stoi(parsedToArray[7]), degreeType);
}
//Here is the commaSeparatedToArray function
string * roster::commaSeparatedToArray(string rowToParse) {
int currentArraySize = 0;
const int expectedArraySize = 9;
string valueArray[expectedArraySize];
int commaIndex = 0;
string remainingString = rowToParse;
while (remainingString.find(",") != string::npos) {
currentArraySize++;
if (currentArraySize <= expectedArraySize) {
commaIndex = static_cast<int>(remainingString.find(","));
valueArray[currentArraySize - 1] = remainingString.substr(0, commaIndex);
remainingString = remainingString.substr(commaIndex + 1, remainingString.length());
}
else {
cerr << "INVALID RECORD. Record has more values then is allowed.\n";
exit(-1);
}
}
if (currentArraySize <= expectedArraySize) {
currentArraySize++;
commaIndex = static_cast<int>(remainingString.find(","));
valueArray[currentArraySize - 1] = remainingString.substr(0, commaIndex);
remainingString = remainingString.substr(commaIndex + 1, remainingString.length());
}
if (currentArraySize < valueArray->size()) {
cerr << "INVALID RECORD. Record has fewer values then is allowed.\n";
exit(-1);
}
return valueArray;
}
1) You can't return arrays in C++. Your code (as I'm sure you know) returns a pointer to an array. That's an important difference.
2) The array is declared locally in the function and therefore no longer exists after the function has exitted.
3) Therefore once you have returned from the function you have a pointer to something which no longer exists. Bad news.
4) You must always consider the lifetime of objects when you program C++. One solution to this problem is to dynamically allocate the array (using new[]). This means that the array will still exist when you exit the function. But it has the signifcant disavantage that you must remember to delete[] the array at a suitable later time.
5) The best solution (in general) is to use a std::vector. Unlike an array a std::vector can be returned from a function. So this option leads to the simplest, most natural code.
vector<string> roster::commaSeparatedToArray(string rowToParse) {
...
vector<string> valueArray(expectedArraySize);
...
return valueArray;
}
Since your array/vector is constant size, you could also use a std::array
array<string, expectedArraySize> valueArray;
To complete the answer that John has already given, I made some example code to show you, how such function could look like.
Parsing, or tokenizing can be easily done with the std::sregex_token_iterator. That is one of the purposes for this iterator. You can see the simplicity of the usage below.
In the function we define a vector af string and use its range constructor to do the whole tokenizing.
Then we make a sanity check and return the data.
Please see:
#include <string>
#include <regex>
#include <iterator>
#include <vector>
#include <algorithm>
#include <iostream>
const std::regex separator(",");
constexpr size_t ExpectedColumnSize = 9;
std::vector<std::string> commaSeparatedToArray(std::string rowToParse)
{
// Parse row into substrings
std::vector<std::string> columns{
std::sregex_token_iterator(rowToParse.begin(),rowToParse.end(),separator ,-1),
std::sregex_token_iterator() };
// Check number of columns
if (columns.size() != ExpectedColumnSize) {
std::cerr << "Error. Unexpected number of columns in record\n";
}
return columns;
}
// test code
int main()
{
// Define test data
std::string testInputData{ "1,2,3,4,5,6,7,8,9" };
// Get the result from the parser
std::vector<std::string> parsedElements{ commaSeparatedToArray(testInputData) };
// show the result on the console
std::copy(parsedElements.begin(), parsedElements.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}

Expected type got Element c++

Im trying to make a object / type that consists of an element of the periodic table. But when i try to use a vector of that object as a parameter, i get this error message expected a type, got ‘Element’
here is my code so far:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
Element(int AtomicNumm, string Symboll, string Namee, double Weightt,
int Neutronss, int Protonss, string ElectronConfigg) {
string Name = Namee;
int AtomicNum = AtomicNumm;
string Symbol = Symboll;
double Weight = Weightt;
int Neutrons = Neutronss;
int Protons = Protonss;
string ElectronConfig = ElectronConfigg;
}
string returnElement(vector<Element> vec, string input) { // error here
if (input.size() == 2) {
for (int i = 0; i < vec.length(); i++) {
}
}
return "";
}
int main(int argc, char*argv[]) {
vector<Element> PT;
string userinput (argv[1]);
return -1;
}
Also, im new to c++. If objects work completely differently here please let me know. (Coming from java)
That's because you haven't declared 'Element' in your program. Syntactically, it is close to definition of a constructor.
To make your program work, i guess you can do following modification to existing element:
class Element {
// your definition of element Here:
// also include default constructor without any implementation
Element() {}
};

Getting "vector subscript out of range" error

I'm currently trying to get "variadic functions" down and just trying to load 4 names in a string vector and then print them out. When I do this with 'int' type and use numbers, it works fine, but when I use a string vector I get the error.
#include "stdafx.h"
#include<cstdio>
#include<cstdarg>
#include<string>
#include<vector>
#include<iostream>
using namespace std;
int count;
vector<string> namesVector;
void names(int count, ...)
{
va_list namesList;
int i; // for loop
va_start(namesList, count);
for (i = 0; i < count; i++)
{
string currentElement;
currentElement = va_arg(namesList, string);
namesVector[i] = currentElement;
}
va_end(namesList);
}
int main()
{
int nameCount = 4;
names(nameCount,"jon", "maggie", "joan", "alfred");
for (int i = 0; i < nameCount; i++)
{
cout << "Name at element " << i << " is: " << namesVector[i] << endl;
}
}
C++ only allows to use trivially-copyable types as variadic arguments. As std::string is constructible from a char* pointer which points to a null-terminated buffer, you may use char* instead of std::string type. Just replace
currentElement = va_arg(namesList, string);
with
currentElement = va_arg(namesList, char*);
in your code. To get rid of this limitation, consider variadic templates, which generate code in compile-time for any type you use.
Your code also contains a run-time error. This:
namesVector[i] = currentElement;
is very likely to crash your program as you didn't allocate any memory in the vector. Vectors are actually dynamic arrays, so you should either pass a size argument to appropriate constructor, or call resize on the vector. In you case you may do neither of it, but just use push_back method:
namesVector.push_back(currentElement);

access private member variable through private member, same class

// M9P369.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
const int MaxSize = 100;
using namespace std;
class Set {
int len; // number of members
char members[MaxSize]; // the set is stored in this array
int find(char ch); // find an element
public:
Set() { len = 0; } // constructor to make a null set initially
int getLength() { return len; } // return number of elements in the set
void showset(); // display the set
bool isMember(char ch); // check for membership
Set operator+(char ch); // overload operator to add an element to the set
Set operator-(char ch); // overload operator to remove an element from the set
Set operator+(Set ob2); // set Union - overloaded by the different type from above overload+ function
Set operator-(Set ob2); // set difference same as above.
};
// Return the index of the element passed in, or -1 if nothing found.
int Set::find(char ch) {
int i;
for (i=0; i < len; i++)
if (members.[i] == ch) return i;
return -1;
}
// Show the set
void Set::showset() {
cout << "{ ";
for (int i=0; i<len; i++)
cout << members[i] << " ";
cout << "}\n";
}
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
I am learning operator overloading, and came across a class access problem.
The line
if (members.[i] == ch) return i;
Gives a tooltip error 'expression must have class type', and compile errors:
\m9p369.cpp(34): error C2059: syntax error : '['
\m9p369.cpp(40): error C2228: left of '.showset' must have class/struct/union
\m9p369.cpp(41): error C2228: left of '.cout' must have class/struct/union
I am defining the private member function find() of class Set, and I get the error upon trying to access the private member char array of the same class, members. Error seems to say I should specify which class it's referring to, why? I already specify the class in the definition:
int Set::find(char ch) {
As I understand, members should be in the scope of the function definition. I looked hard for any stray characters I couldn't find anything odd, all parenthesis seem to match.
Problem is here:
members.[i]
It should be just
members[i]
Remeove the . from
if (members.[i] == ch) return i;
~~~~~~~~~~~^

Initializing chained hash table to NULL. Get "lvalue required as left operand of assignment" error. Why? Here is my code:

I am trying to create a chained hash table. I have started by building a dynamic array and am now trying to initialize each array pointer to NULL. But I get the error "lvalue required as left operand of assignment". Why? Here is my code:
#include <iostream> // for i/o functions
using namespace std;
const int HTSIZE = 997; //size of the hash table
struct CHTNode
{
int value;
CHTNode *next;
};
void InitializeTable(CHTNode* &cHT);
int main()
{
CHTNode *chainedHT;
chainedHT = new(nothrow) CHTNode[HTSIZE];
if (chainedHT == NULL)
{
cout << "ERROR: Memory allocation error"
<< endl;
return 1;
} //end if
else
{
InitializeTable(chainedHT);
}
}
void InitializeTable(CHTNode* &cHT)
{
for (int i = 0; i < HTSIZE; i++)
&cHT[i] = NULL; //ERROR FOR THIS LINE
}
The address-of operator & returns the address of the given expression, so &cHT[i] evaluates to the address of the ith element of cHT. It seems you're trying to assign to the variable cHT[i], but what you're doing right now is trying to assign to the address value of cHT[i], which makes no more sense than trying to assign to a constant.
You do not have an array of pointers. You allocated an array of objects of type CHTNode.
You could value initialize this array when it was allocated. For example
chainedHT = new(nothrow) CHTNode[HTSIZE] {};
If you want to write a separate function that zero-injitialize each element of the array then the function could be declared like
void InitializeTable( CHTNode* cHT, int n );
and defined like
void InitializeTable( CHTNode* cHT, int n )
{
for ( int i = 0; i < n; i++ ) cHT[i] = {};
}
As for erroneous statement
&cHT[i] = NULL;
then it does not make a sense. Expression &cHT[i] is a temporary object that you are try to assign.