Error in using vector pointer in a function - c++

I have this code, but it won't compile and i can't understand what is wrong - i guess the pointering of the vector is not correct.
My idea was to collect some numbers in main() and store them in a vector and array, and then pass the memory address of them to a function, and using a pointers to print the data stored.
I came up with this when i read something about pointers which said that i should use them in order to save memory, so IMO the code below will not copy the contents of the vector and the array but use a pointer to access their location in memory - that's what i want to do.
#include <iostream>
#include <vector>
using namespace std;
void function(vector<int>* a, int *s)
{
cout << "function starts.." << endl;
for(int i=0;i<a->size();i++)
{
cout << a[i] << endl;
cout << s[a[i]] << endl;
}
cout << "function ends..." << endl;
}
int main(void)
{
vector<int> m;
int s[102];
for(int i=0;i<10;i++)
{
m.push_back(i*i);
s[i*i] = i-2;
}
function(&m, &s);
return 0;
}
I receive several errors on compiling, something is wrong.
Please tell me what's wrong with my code and how to fix it. thank you...

You should pass the vector by reference, not by pointer:
void function(vector<int>& a, int *s)
And then
function(m, ...);
Using [] on a pointer to a vector would certainly cause strange problems because it behaves as if a pointed to an array of std::vectors (while it actually only points to one). The vectors itself are never indexed by that. You could also use (*a)[...] to index the vector by the pointer.

if you insist in parsing by pointer then the correct syntax shoulld be:
void function(vector<int>* a, int *s[])
{
cout << "function starts.." << endl;
for(int i=0;i<a->size();i++)
{
cout << (*a)[i] << endl;
cout << (*s)[(*a)[i]] << endl;
}
cout << "function ends..." << endl;
}

First of all in the main program s is a pointer to an int, while m is a vector. Thus the function call should be as follows:
function(&m, s);
Secondly in the function a is a pointer to a vector, so should be indexed as follows: (*a)[i].
However you should really be using const references to pass your vector around:
void function(const vector& a, int *s)
{
..
cout << a[i] << endl;
..
}
And call it like:
function(m, s);

(corrected)
&s is in fact int(*)[102]: pointer to a pointer to an array of 102 items.
You should just say
function(&m, s);
This is because by old C legacy rule, an array is essentially a const pointer to its item with index 0. So s is already int*

This version works:
#include <iostream>
#include <vector>
using namespace std;
void function(const vector<int>& a, int s [102])
{
cout << "function starts.." << endl;
for(int i=0;i<(int)a.size();i++)
{
cout << a [i] << endl;
cout << s[a [i]] << endl;
}
cout << "function ends..." << endl;
}
int main(void)
{
vector<int> m;
int s[102];
for(int i=0;i<10;i++)
{
m.push_back(i*i);
s[i*i] = i-2;
}
function(m, s);
return 0;
}

Related

How do I read a .txt file with an undefined number of values using an array (C++)?

I am entirely new to programming so I'm sorry if I don't explain this well. For my C++ assignment I had to write an object-oriented program that reads the names from a text file (the text file is just a list of first names) and prints them to the console in alphabetical order using an array. Originally, the description of the assignment said that the file had 20 names, so I based my code around that. The program works, but now it turns out the assignment description was inaccurate and we shouldn't assume that the text file has a specific number of names. How do I convert my code from specifically reading 20 names to instead reading an undefined number of names, while still using an array?
I don't fully understand the concepts that I'm implementing so it's difficult for me to know how to change my code while still following the requirements of the assignment. Here is my code:
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
using namespace std;
class Names
{
private:
ifstream inStudents;
string studentNames[20];
string name;
int j;
public:
Names();
~Names();
void openFile(string);
void testFile();
void readFile();
void sortNames();
void closeFile();
void display();
};
Names::Names()
{
}
Names::~Names()
{
}
void Names::openFile(string d)
{
inStudents.open(d);
}
void Names::testFile()
{
if (!inStudents)
{
cout << "File did not open" << endl;
exit(10);
}
}
void Names::readFile()
{
cout << "Reading the input file..." << endl;
int j = 0;
while (inStudents >> name && j < 20)
{
studentNames[j++] = name;
}
}
void Names::sortNames()
{
sort(studentNames, studentNames + 20);
}
void Names::closeFile()
{
inStudents.close();
}
void Names::display()
{
cout << endl << "The alphabetical list: " << endl << endl;
for (int i = 0; i<20; i++)
cout << studentNames[i] << " " << endl;
cout << endl << endl;
}
int main()
{
Names r;
r.openFile("students.txt");
r.readFile();
r.testFile();
r.sortNames();
r.display();
r.closeFile();
return 0;
}
You can use std::vector object instead of a regular array. It will look like that:
vector<string> studentNames;
Now, instead of using the following line to insert a name to a known place in the array:
studentNames[j++] = name;
use:
studentNames.push_back(name);
//or
studentNames.emplace_back(name);
The the while loop inside your readFile function, will look like this:
while (inStudents >> name)
{
studentNames.push_back(name);
}
To display it now, all you have to change in your display function is the range. The vector object include a function named size which returns you the current vector size, or in other words- the elements' count that the vector includes. It will seem like the following line:
for (int i = 0; i < studentNames.size(); i++)

C++ Error: no viable conversion from returned value of type

I am trying to pass a vector to a function as an argument/parameter in order to print/return contents of that list/array/vector but when I compile the code I'm facing this error:
here's the code:
#include <iostream>
#include <vector>
using namespace std;
int printVector(vector<int> vec_name){
return copy(vec_name.begin(), vec_name.end(), ostream_iterator<int>(cout," ")); // returning contents of the array/vector
}
int main(){
vector<int> array;
for(int i=0;i<=10;i++){
array.push_back(i); // inserting values to the array
}
printVector(array); // Printing the vector array
}
PROBLEM SOLVED:
used for loop in order to print each value from the vector:
void printVector(vector<int> &vec_name){
for(int i=0; i<vec_name.size(); i++){
cout << vec_name[i] << " ";
}
}
void printVector(vector<int> const & vec_name)
{
for(size_t i = 0; i<vec_name.size(); i++){
cout << vec_name[i] << " ";
}
cout << "\n";
}

Access to the struct elements. Is it possible to access like a vector?

I have the following example (simplified) using a struct:
#include <iostream>
#include <algorithm>
#include <time.h>
using namespace std;
struct s_str
{
int a=1,b=2,c=3;
};
int main(void)
{
s_str str;
int sel;
srand(time(NULL)); //initialize random seed
sel = rand() % (3); //generate a random number between 0 and 2
cout << "sel: " << sel << endl;
cout << "str: " << str.??? << endl;//I was wondering to output a, b or c
return 0; //depending whether sel=0,1,2respectively.
}
When the struct "str" is defined, we can access to each element by using the opertor "." followed by the name of the element. For instance "str.c" will give us the number 3.
However in this example we don't know the element of "str" to output when programing because it's randomly selected by sel.
I don't know how to output "str.???" from sel number, that is, str.a if sel=0, str.b if sel=1, and str.c if sel=3.
I tried something like "str.[sel]", but it didn't work. Can you help me?
PD: I don't want to bother too much, but how to solve the same problem but now supposing that a,b and c have different variable type. For example:
int a=1,b=2;
string c="hola";
I tried to do it with two operators, but it didn't compile because they were overloaded.
As mentioned you can't do this without providing a certain mapping and indexing operator. The following should work well:
struct s_str
{
int a=1,b=2,c=3;
int& operator[](int index) {
switch(index) {
case 0:
return a;
case 1:
return b;
case 2:
return c;
default:
throw std::out_of_range("s_str: Index out of range.");
break;
}
}
};
int main() {
s_str s;
cout << s[0] << ", " << s[1] << ", " << s[2] << endl;
// cout << s[42] << endl; // Uncomment to see it fail.
return 0;
}
In general, no.
If the only distinguishing feature of the elements of the struct is their index, define a vector or array in the struct.
If you sometimes want to refer to the elements by name and sometimes by position, define an operator []( int ) for the struct.
Te easiest way, if you have only a couple of ints in your structure is:
struct s_str
{
int a = 1, b = 2, c = 3;
int& operator[] (size_t t) {
assert(t<3); // assumption for the following to return a meaningful value
return (t == 0 ? a : (t == 1 ? b : c));
}
};
You'd access with
cout << "str: " << str[sel] << endl;
and you could even use int to assign, because it's by reference:
str[sel] = 9;
cout << "a,b,c=" << str.a << "," << str.b << "," << str.c << endl;

Trouble with types when passing vector to function in c++

I am starting a c++ class having never done anything in the language before, and I'm pretty confused by vectors.I made a toy example and I don't quite understand why the doubles that I put into a vector become vector's. Here is the code:
#include <iostream>
#include <vector>
using namespace std;
vector<double> a;
void func(vector<double> *);
int main()
{
for (int i = 0; i < 100; i++)
{
a.push_back(double(i));
}
func(&a);
return 0;
}
void func(vector<double> *vec)
{
cout << double(vec[0]) << endl;
return;
}
It ends up giving me this error:
error: cannot convert 'vector' to 'double' without
a conversion operator
and I have no idea what that means. What exactly is happening here and how can I cast a vector into a double?
You don't need to mix using pointers * with std::vector.
Method 1 (not recommended):
Change
cout << double(vec[0]) << endl;
to
cout << double((*vec).at(0)) << endl;
Method 2:
Change
void func(vector<double> *vec)
to
void func(vector<double> vec)
or
void func(const vector<double> &vec)
Change
func(&a);
to
func(a);
The reason for the actual error is more due to a misunderstanding of pointers than vectors . The problem is that you are passing a pointer to a vector. If you want to use the vector itself, then you would do:
cout << (*vec)[0] << endl;
* will dereference the pointer to get the actual vector instance rather than an index into an address which is what you were doing before.
But, as pointed out in the other answer, it is safer just to pass the vector by reference (or better yet, const reference):
void func(const vector<double>& vec)
{
cout << vec[0] << endl;
return;
}
then call as:
func(a);
Another way to use vectors is with a std::vector< TYPE >::const_iterator like this;
#include <iostream>
#include <vector>
double func(std::vector<double>::const_iterator iter);
int main()
{
std::vector<double> vec;
for (double i = 0.0; i < 1; i += 0.1){
vec.push_back(i);
}
std::cout<< func(vec.begin()+3) << " "
<< func(vec.begin()+6) << std::endl;
return 0;
}
double func(std::vector<double>::const_iterator iter){
return *iter;
}
outputs;
0.3 0.6

c++ references array

I wounder how i can make this code work?
#include <iostream>
using namespace std;
void writeTable(int (&tab)[],int x){
for(int i=0;i<x;i++){
cout << "Enter value " << i+1 <<endl;
cin >> tab[i] ;
}
}
int main(void){
int howMany;
cout << "How many elemets" << endl;
cin >> howMany;
int table[howMany];
int (&ref)[howMany]=table;
writeTable(ref,howMany);
return 0;
}
And here are the errors that I have:
|4|error: parameter ‘tab’ includes reference to array of unknown bound ‘int []’|
|18|error: invalid initialization of reference of type ‘int (&)[]’ from expression of type ‘int [(((unsigned int)(((int)howMany) + -0x00000000000000001)) + 1)]’|
|4|error: in passing argument 1 of ‘void writeTable(int (&)[], int)’|
Thanks for help
If you are intending to pass the size of the array, then remove the reference
void f(int a[])
is equivalent to
void f(int* a)
so no copying will be done, if that is the concern.
If you want to take an array by reference, then you MUST specify the dimension. e.g.
void f(int (&a)[10])
Naturally, the best of the two is the third solution, which is to use std::vector's and pass them by reference, reference to const or by value if needed. HTH
Here is a slightly more C++ style of doing it:
#include <iostream>
#include <vector>
void writeTable(std::vector<int> &tab)
{
int val;
for (unsigned int i=0; i<tab.size(); i++)
{
std::cout << "Enter value " << i+1 << std::endl;
if (std::cin >> val)
{
tab[i] = val;
}
}
}
int main()
{
int howMany;
std::cout << "How many elements?" << std::endl;
std::cin >> howMany;
std::vector<int> table(howMany);
writeTable(table);
return 0;
}
You need not specify the dimension of the array if you make writeTable a function template.
template <typename T,size_t N>
void writeTable(T (&tab)[N]) //Template argument deduction
{
for(int i=0 ; i<N ; i++){
// code ....
}
}
.
int table[howMany]; // C++ doesn't have Variable Length Arrays. `howMany` must be a constant
writeTable(table); // type and size of `table` is automatically deduced
Following Amardeep's answer, here is a C++11 way to do it:
#include <iostream>
#include <vector>
void writeTable(std::vector<int> &tab)
{
int val;
for (auto& cell : tab)
{
std::cout << "Enter value " << i+1 << std::endl;
if (std::cin >> val)
{
cell = val;
}
}
}
int main()
{
int howMany;
std::cout << "How many elements?" << std::endl;
std::cin >> howMany;
std::vector<int> table(howMany);
writeTable(table);
return 0;
}
Note the range-based for used in writeTable.
Arrays of references are illegal, if that is what you are trying to do. It's not 100% clear to me from the title.