I want to store a vector in a structure and then append to the vector from a function. Does this even make sense or can I only create elements in my vector when creating it? If no, where is the error in the code below, because if I execute it, it simply prints nothing. I want it to store the numbers 0-4 as components of the vector nums in holder.
#include "iostream"
#include "vector"
using namespace std;
struct layers{
vector<float> nums;
};
void range(layers layer){
for(int n = 0; n< 5; n++){
layer.nums.push_back(n);
}
}
int main(){
layers holder;
range(holder);
for(int k = 0; k < holder.nums.size(); k++){
std::cout << holder.nums[k] << " ";
}
return 0;
}
You have to pass the layer parameter by reference, not by value. Instead of void range(layers layer), do void range(layers &layer).
If you pass by value, you are making a copy of the vector and then modify this copy inside the function, so your original vector remains untouched. If you pass by reference, the original vector is modified.
Try it online!
#include "iostream"
#include "vector"
using namespace std;
struct layers{
vector<float> nums;
};
void range(layers & layer){
for(int n = 0; n< 5; n++){
layer.nums.push_back(n);
}
}
int main(){
layers holder;
range(holder);
for(int k = 0; k < holder.nums.size(); k++){
std::cout << holder.nums[k] << " ";
}
return 0;
}
Output:
0 1 2 3 4
Related
I wanted to create a matrix with vectors. In the below code, I created a vector with each entry containing a pointer to another vector(myvector) that acts as columns. I push random values to the myvector (i.e. columns). But when I try to access the values of arrays, it pops an compile error saying "error: no match for 'operator*' (operand type is 'std::vector<int>') at the cout statement. I wonder how do I access the values. I'm pretty sure this is a naive question.
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
std::vector<vector<int>*> main;
for(int j=0; j<3; j++){
vector<int> *myvector = new vector<int>;
main.push_back(myvector);
}
main[0]->push_back(1);
main[0]->push_back(4);
main[1]->push_back(6);
main[1]->push_back(7);
main[1]->push_back(8);
main[2]->push_back(3);
for(int j=0; j<3; j++){
for(uint32_t i=0; i<main[j]->size(); i++)
std::cout<<main[j][i]<<" ";
cout<<"\n";
}
return 0;
}
You could just have done
vector<vector<int>> main;
each index of vector main represents another vector
so to push a number in the first column you can do
main[0].push_back = (_number_)
To access a number in first row in first column we can do main[0][0]
This example shows both the syntax you where looking for, and also an example of how you should use std::vector without new/delete.
#include <iostream>
#include <vector>
#include <memory>
// using namespace std; <== teach yourself NOT to do this.
// https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice
void access_pointers_in_2d_vector()
{
std::vector<std::vector<int>*> values; // don't call your variables main!
for (int j = 0; j < 3; j++)
{
std::vector<int>* myvector = new std::vector<int>;
values.push_back(myvector);
}
values[0]->push_back(1);
values[0]->push_back(4);
values[1]->push_back(6);
values[1]->push_back(7);
values[1]->push_back(8);
values[2]->push_back(3);
for (int j = 0; j < 3; j++)
{
for (uint32_t i = 0; i < values[j]->size(); i++)
{
//==================================================================
// this is the syntax you're looking for
// first dereference the pointer then use operator[]
std::cout << (*values[j])[i] << " ";
//==================================================================
}
std::cout << "\n";
}
// don't forget to cleanup your memory!
// if you typed new somewhere then there should
// ALWAYS be a matching delete in your code too!
for (int j = 0; j < 3; j++)
{
delete values[j]; // <<==== !!!!!!!
}
}
// for dynamic memory managment new/delete aren't recommended anymore.
// use std::unique_pointer (or if your design really requires it std::shared_ptr)
void using_unique_pointer()
{
// If you really need pointers, use std::unique_ptr
// it will prevent you from introducing memory leaks
const std::uint32_t size = 3ul;
std::vector<std::unique_ptr<std::vector<int>>> values(size);
for (auto& p : values)
{
p = std::make_unique<std::vector<int>>();
}
values[0]->push_back(1);
values[0]->push_back(4);
values[1]->push_back(6);
values[1]->push_back(7);
values[1]->push_back(8);
values[2]->push_back(3);
// output loop is same as for normal pointers.
// no need to call delete, std::unique_ptr will do that for you
}
void without_pointers()
{
// However your whole code in idiomatic c++ should look like this.
// https://en.cppreference.com/w/cpp/container/vector/vector constructor (10)
// https://en.cppreference.com/w/cpp/language/range-for these loops avoid bugs related to
// letting indices go out of bounds.
std::cout << "\nusing (nested) initializer list and range based for loops : \n";
std::vector<std::vector<int>> rows{ {1,4}, {6,7,8}, {3} };
for (const auto& row : rows)
{
for (const auto& value : row)
{
std::cout << value << " ";
}
std::cout << "\n";
}
}
int main()
{
access_pointers_in_2d_vector();
using_unique_pointer();
without_pointers();
return 0;
}
I have a variable k of type int to set the length of a dynamically allocated int array:
int *Numbers = new int[k];
But because of this I cannot iterate over the array, I get an error:
"no matching begin function was found required for this range-based for statement"
I also cannot get the length of the array using size();
Here's the complete code:
#include <iostream>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
int *Numbers = new int[k];
for (int i : Numbers) {// (There is a error)
}
for (int i = 0; i < size(Numbers); i++) {
}
}
Prefer using a std::vector instead of a std::array. (Like #tadman mentioned.)
Here is your code using std::vector instead:
#include <iostream>
#include <vector>
int main()
{
int b, k;
std::cin >> b >> k;
std::vector<int> Numbers(b,k); // Fills the vector "Numbers" with nth number of elements with each element as a copy of val.
for (int i : Numbers)
std::cout << i << std::endl;
for (int i = 0; i < Numbers.size(); i++)
std::cout << Numbers[i] << std::endl;
return 0;
}
Say I want 10 elements with the number 5.
Output:
10
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
Also consider not using namespace std;.
The simple and recommended solution is to use std::vector, however if you really want a dynamically allocated array and to use iterator like features on it, you can use iterator_range from boost library, which allows you to create an iterator range for it thus making it usable in range based for loops and in functions like std::size.
Live demo
#include <iostream>
#include<boost/range.hpp>
int main()
{
int k = 5;
int *Numbers = new int[k]{1,4,5,7,8};
auto arr = boost::make_iterator_range(Numbers, Numbers + k);
for (int i : arr) { //range based loop
std::cout << i << " ";
}
std::cout << std::endl << "Size: " << arr.size(); //print size
//or std::size(arr);
}
Output:
1 4 5 7 8
Size: 5
Range-based for loops work with arrays, but not work with pointers. The Actual issue is that arrays is actually a pointer and not an array.try to use simple array.
Using pointers is problematic for many reasons. The simple solution to your problem is to use a vector
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
vector<int> Numbers(k);
for (int i : Numbers) {
cout << i << endl;
}
for (int i = 0; i < Numbers.size(); i++) {
cout << Numbers[i] << endl;
}
}
C array does not have default iterator and thus there is no begin() and end() functions that are used to iterate over array when you use statment like this:
for (int i : Numbers)
You can check range-for reference:
range_expression - any expression that represents a suitable sequence (either an array or an object for which begin and end member functions or free functions are defined, see below) or a braced-init-list.
Okay, so since the dynamic array does not have a default iterator, do not use the for-each loop, instead consider using the regular for loop.
Also, mind the the size function will not work for an array (or dynamic array) and you need to remember the size, since it's not possible to get the size from the pointer only. Hence, this code would work:
#include <iostream>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
int *Numbers = new int[k];
const int SIZE = k;
for (int i = 0; i < SIZE; i++) {
cout << i << ' ';
}
}
You need to dereference *Numbers by using the * if you want to iterate over the array because *Numbers is a pointer to an integer which points to the first element of your array.For Example :
#include <iostream>
using namespace std;
int main()
{
int k = 10;
int *numbers = new int[k];
//filling the array
for(int i = 0 ; i < k ; ++i) {
*(numbers + i) = i ;
}
//output array element
for(int i = 0 ; i < k ; ++i) {
cout << numbers + i << " is the address of "<<*(numbers + i) << endl;
}
return 0;
}
The output is :
0x6f1750 is the address of 0
0x6f1754 is the address of 1
0x6f1758 is the address of 2
0x6f175c is the address of 3
0x6f1760 is the address of 4
0x6f1764 is the address of 5
0x6f1768 is the address of 6
0x6f176c is the address of 7
0x6f1770 is the address of 8
0x6f1774 is the address of 9
Unfortunatly, you can't get the size of your array with *Numbers because it's not an array but a pointer.
I'm trying to fill 2D vector in C++ with characters, but when I run this code it ends with one line characters (*..).
How can I fill 2D vector like this:
*.*
.**
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<char> > vec2D;
std::vector<char> rowV;
unsigned int row=2;
unsigned int col=3;
char c;
unsigned int temp=0;
while(temp!=col)
{
while(rowV.size()!=row)
{
std::cin>>c;
rowV.push_back(c);
}
vec2D.push_back(rowV);
++temp;
}
return 0;
}
You should clear rowV after each insertion, otherwise it will be full and no other characters will be added. Also, row should be swapped by col and vice-versa, otherwise you will get a 3x2 (and not 2x3) 2D vector.
while(temp!=row)
{
while(rowV.size()!=col)
{
std::cin>>c;
rowV.push_back(c);
}
vec2D.push_back(rowV);
rowV.clear(); // clear after inserting
++temp;
}
It helps to know what [pushing back a 2DVector with an empty 1D vector] looks like.
See the example below.
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
//-v-----A FUNCTION TO PRINT 2D VECTORS
template<typename T> //We don't know what type the elements are yet, so we use a template
void printVec2D(vector<vector<T>> a) // a is the name of our input 2Dvector of type (T)
{
for (int i = 0; i < a.size(); i++) {// a.size() will equal the number of rows (i suppose rows/columns can depend on how you look at it)
for (int j = 0; j < a[i].size(); j++) {// a[i].size() is the size of the i'th row (which equals the number of columns, foro a square array)
std::cout << a[i][j] << "\t";
}
std::cout << "\n";
}
return;
}
//-^--------
int main()
{
int X = 3; int Y = 3;
int VectorAsArray[3][3] = {{1,2,3},
{14,15,16},
{107,108,109}};
vector<vector<int>> T;
for (int i = 0; i < X; i++)
{
T.push_back({});// We insert a blank row until there are X rows
for (int j = 0; j < Y; j++)
{
T[i].push_back(VectorAsArray[i][j]); //Within the j'th row, we insert the element corresponding to the i'th column
}
}
printVec2D(T);
//system("pause"); //<- I know that this command works on Windows, but unsure otherwise( it is just a way to pause the program)
return 0;
}
I'm trying to convert my array to a vector, yet I'm having trouble printing it.
It says in int main() in my for loop that v is undefined. When I define
vector v; inside int main() the program compiles and runs and yet prints nothing. What am I doing wrong?
#include <iostream>
#include <vector>
using namespace std;
vector<int> a2v(int x[], int n)
{
vector<int> v(n);
for(int i = 0; i < n; i++)
{
v.push_back(x[i]);
}
return(v);
}
int main()
{
vector<int> a2v(int x[], int n);
int array[] = {11,12,13,14,15,16,17,18};
a2v(array, 8);
for(int i = 0; i < v.size(); i++)
{
cout << v[i] <<" ";
}
cout << endl;
return(0);
}
This is your program corrected:
#include <iostream>
#include <vector>
using namespace std;
vector<int> a2v(int x[], int n)
{
vector<int> v(0);
v.reserve(n); //optional
for(int i = 0; i < n; i++)
{
v.push_back(x[i]);
}
return(v);
}
int main()
{
int array[] = {11,12,13,14,15,16,17,18};
auto v = a2v(array, 8);
for(size_t i = 0; i < v.size(); i++)
{
cout << v[i] <<" ";
}
cout << endl;
return(0);
}
There were 2 errors:
In the function a2v, you instantiated a vector of 0 with length n, and then you pushed back other elements;
You were not defining v inside the main, as the return value of a2v
The vector you want to read is the return of the a2v function.
But there is a lot more simpler than that to go from C-array to vector array , I put here the example in found the vector reference web page :
http://www.cplusplus.com/reference/vector/vector/vector/
int myints[] = {16,2,77,29};
std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
When you define a variable, such as your vector v, you always do it in a certain scope. The body of a function such as a2v, or main, is an example of a possible scope. So if you only do it in the function a2v, that's the only scope where it will be visible.
It says in int main() in my for loop that v is undefined.
Well it will be because there is no v in main()
a2v(array, 8);
The above function call returns a vector so you need to collect the returned vector like
vector<int> v=a2v(array,8)
Also,
vector<int> v(n);//creates a vector of size n
for(int i = 0; i < n; i++)
{
v.push_back(x[i]);//adds n more elements to the vector
}
The returned vector has 2n elements and not n
Finally you could directly create a vector from an array as
vector<int> v(arr,arr+n);//where n is the number of elements in arr
I am supossed to do a code using function which after asking the user for input,puts number before the vector like this:
if vector is 11,12,13,14
new vector is 1 11 2 12 3 13 4 14 until the vector finishes and then I have to print it but I get an error of vector subscript out of range,aprecciate any help.
Here is my code
#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<double> llena_vector(int x,vector<double> ingreso)
{
cout<<"Ingrese numeros: ";
while(cin>>x);
ingreso.push_back(x);
return ingreso;
}
vector<double> arma_vector(int contador,vector<double> intercalado)
{
int i=0;
for(contador=1;contador< intercalado.size()+1;contador++);{
intercalado.insert(intercalado.begin()+i,contador);i++;}
return intercalado;
}
vector<double> imprime_vector(int cuenta,vector<double> imprimir)
{
for(cuenta=0;cuenta<imprimir.size();cuenta++);
cout<<imprimir[cuenta]<<" ";
return imprimir;
}
int main()
{
int y=0;
int q=0;
int w=0;
int f=0;
vector<double> usuario;
vector<double> guardar;
vector<double> resultado;
vector<double> print;
guardar= llena_vector(y,usuario);
resultado=arma_vector(q,guardar);
print=imprime_vector(w,resultado);
system("pause");
}
Here is a cleaner version of the code, in working condition.
#include <iostream>
#include <vector>
using namespace std;
void fill_vector(vector<double>& v)
{
cout << "Enter 5 numbers." << endl;
for (int i = 0; i < 5; ++i)
{
double d;
cin >> d;
v.push_back(d);
}
}
void insert_count(vector<double>& v)
{
size_t size = v.size();
for (size_t i = 0, j = 0; i < size; ++i, j += 2)
{
vector<double>::iterator pos = v.begin() + j;
v.insert(pos, i + 1);
}
}
void print_vector(vector<double>& v)
{
for (size_t i = 0; i < v.size(); ++i)
cout << v[i] << " ";
cout << endl;
}
int main()
{
vector<double> v;
fill_vector(v);
insert_count(v);
print_vector(v);
}
Like others (may have) pointed out:
you didn't need to pass by value (you're basically passing around a bunch of copies), you can pass by reference instead to reduce overhead and speed it up
you shouldn't put semicolons (;) directly behind your loop statements
size_t is often better than int when looping on size
you included <string> when it wasn't being used
you were passing arguments that weren't needed (e.g. a counter)
you used a while loop for user input, but it's only appropriate when piping in data otherwise it will loop forever; a for loop with a known count is more appropriate for user input
the function that inserted numbers between the existing elements had an error, you were incorrectly calculating the position to insert
your code formatting was a mess, making the code very difficult to read
you shouldn't pollute the namespace (i.e. using namespace std), but I left it as is since it's common in example code
if you're using C++11, I recommend using a for-each loop for printing the vector, and the auto keyword when declaring the iterator
i guess there is a typo: you should remove the last ; in for(cuenta=0;cuenta<imprimir.size();cuenta++);
Edit: as pointed by jrd1, you have this typo in all your for and while loops...
To begin with, your code has a number of issues. But, I've modified it to keep it as similar to your original.
#include <iostream>
#include <string>
#include <deque>
#include <cstdlib>
using namespace std;
deque<double> llena_deque(int x, deque<double> ingreso)
{
cout<<"Ingrese numeros: ";
while(cin>>x)
ingreso.push_back(x);
return ingreso;
}
deque<double> arma_deque(int contador, deque<double> intercalado)
{
int size = intercalado.size()+1;
for(int i=1; i < size; ++i) {
cout << i << endl;
intercalado.push_front(i);
}
return intercalado;
}
deque<double> imprime_deque(int cuenta, deque<double> imprimir)
{
for(cuenta=0;cuenta<imprimir.size();cuenta++)
cout << imprimir[cuenta] << " ";
return imprimir;
}
int main()
{
int y=0;
int q=0;
int w=0;
int f=0;
deque<double> usuario;
deque<double> guardar;
deque<double> resultado;
deque<double> print;
guardar= llena_deque(y,usuario);
resultado=arma_deque(q,guardar);
print=imprime_deque(w,resultado);
return 0;
}
All your loops had ; at the end of them. That's one reason why you're getting your errors, as the semi-colon terminates a statement - hence, your loops were never truly accessing the vectors, which is why you were getting the memory access violations.
You're passing all your memory by value (which could potentially be slow). Consider using references.
Your operations suggest that you constantly need to keep pushing new data in front of your vector. If so, then use deque (as I did) as it is has functionality designed explicitly for that purpose (insert operations at both ends).
Although, I will say that the logic of your code is quite puzzling at times: i.e. in arma_vector, why pass the value of contador if you don't even use it? You could have used i instead...