How to print vector<int> to terminal in c++ [duplicate] - c++

This question already has answers here:
How do I print out the contents of a vector?
(31 answers)
Closed 4 years ago.
I am trying to print a vector of integers to the terminal using "cout", but I get an error message during compiling:
no match for 'operator<<' (operand types are 'std::basic_ostream' and 'std::vector')
cout << "Disparity at points: " << disparityVector << endl;
The snippet of code looks like this:
vector<int> disparityVector;
for ( int i=0; i<drawPixels.size(); i++) // Get disparity at each point of the drawn line
disparityVector.push_back((int)disparityMapOutput.at<int16_t>(pos[i].y, pos[i].x));
cout << "Disparity at points: " << disparityVector << endl;
There is no error with assigning the values to the vector, only the "cout" part of the code is making errors

For example, using ostream_iterator.
Sample from that page:
// ostream_iterator example
#include <iostream> // std::cout
#include <iterator> // std::ostream_iterator
#include <vector> // std::vector
#include <algorithm> // std::copy
int main () {
std::vector<int> myvector;
for (int i=1; i<10; ++i) myvector.push_back(i*10);
std::ostream_iterator<int> out_it (std::cout,", ");
std::copy ( myvector.begin(), myvector.end(), out_it );
return 0;
}

You'll need something like below, if you want to do it the way you've coded it.
template<class T>
inline std::ostream& operator<< (std::ostream& o, std::vector<T> const& v) {
for (auto const& i : v)
o << i << " ";
return o;
}

std::ostream& operator<<(std::ostream& os, const vector<int>& v)
{
std::ostream_iterator<int> _oit(cout, " ");
std::copy(v.begin(), v.end(), _oit);
return os;
}

This error means that vector<T> has no operator<< implementation.
You need to iterate over your vector and print each element:
for(int i = 0; i < disparityVector.size; i++) {
cout << disparityVector[i];
}
cout << endl;

Related

how do i print elements of vector of pair? [duplicate]

This question already has answers here:
Printing a `vector<pair<int, int>>`
(4 answers)
Closed 8 months ago.
#include <iostream>
#include <utility>
#include <vector>
int main() {
std::vector<std::pair<int,int>> v;
v.push_back({10,20});
// This works
std::cout << v[0].first << " " << v[0].second << "\n";
// But I'd like to just be able to do
std::cout << v[0] << "\n";
}
How can we print a vector of pairs instead of printing separate values of the pairs like v[i].first and v[i].second? I want to print like cout << v[i]; but it shows an error.
std::pair does not have a defined operator<<. Therefore, you have to define it yourself.
You can use this template to print any std::pair<T, Y> you want, as long as T and Y have defined operator<< as well:
#include <iostream>
#include <utility>
template<typename T, typename Y>
auto operator<<(std::ostream& stream, std::pair<T,Y> const& p) -> std::ostream& {
stream << p.first << ' ' << p.second;
return stream;
}
auto main() -> int {
std::pair<int,int> p{1, 2};
std::cout << p << '\n';
}

Overloading << operator to print vector<MyClass>

I'm trying to overload the << operator to print a vector that contains elements of type Position (vector).
I managed to overload the << operator for type Position, but I can't figure out how to do it for vector. Can you help?
//position.h
#ifndef POSITION_H
#define POSITION_H
#include <iostream> // using IO functions
using namespace std;
class Position {
private:
int row;
int column;
public:
friend ostream& operator<<(ostream& os, const Position& P);
friend ostream& operator<<(ostream& os, const vector<Position>& VP);
};
#endif
//position.cpp
#include"Position.h"
#include <iostream> // using IO functions
#include<vector>
ostream& operator<<(ostream& os, const Position& P)
{
os << '(' << P.row << ',' << P.column << ')' << endl;
return os;
}
ostream& operator<<(ostream& os, const vector<Position>& VP)
{
Position placeholder;
for (int i = 0; i != VP.size(); i++)
{
placeholder = VP.at(i);
cout << placeholder << endl;
}
return os;
}
int main()
{
Position C1(2, 1);
Position C2(3, 1);
Position C3(4, 1);
vector<Position> cans;
cans.push_back(C1);
cans.push_back(C2);
cans.push_back(C3);
cout << cans;
system("pause");
}
I'm sure there's a duplicate on StackOverflow somewhere, but I cannot find it. I'm a bit surprised about this question, as I don't really see a critical issue at first sight. Did you get a compiler error or segmentation fault?
Every time you assign to Placeholder, you make a copy. This is not necessary at all: you can directly access the element at the index. As you limit the index to 0 to size(), you don't have to worry about going out-of-bounds, so don't use .at(i), which throws an exception if you go out of bounds. Just use VP[i].
Also not that std::endl flushes the buffer, which is slow. A normal enter/end-line can be achieved with the '\n' character.
Finally, using namespace std; is considered bad practice.
You have multiple options for processing the elements of the vector:
index-based for loop:
for (int i = 0; i != VP.size(); ++i) {
os << VP[i] << '\n';
}
Iterator-based for loop
for (auto it = cbegin(VP); it != cend(VP); ++it) {
os << *it << '\n';
}
range-based for loop
for (auto const& el : VP) {
os << el << '\n';
}
Algorithm for(each) loop
std::for_each(cbegin(VP), cend(VP),
[](auto const& el) { os << el << '\n'; });
Copy to ostream_iterator
std::copy(cbegin(VP), cend(VP),
std::ostream_iterator<Position>(os, "\n"));
Note that here you could also write <decltype(VP)::value> instead of <Position> to keep it generic, but that might be overkill in this situation.
And the last two have a C++20 ranges equivalent:
std::ranges::for_each(VP,
[](auto const& el) { os << el << '\n'; });
std::ranges::copy(VP,
std::ostream_iterator<Position>(os, "\n"));
Note:
friend ostream& operator<<(ostream& os, const vector<Position>& VP); doesn't have to be a friend of Position! It doesn't require access to the private members.

C++ Displaying a vector

I'm learning C++ so my question might seem a bit stupid. I wanted to build a function that print every element in a vector. I come up with that but it seems to display the address of every element. I google it and find a nice solution but i wanted to do it this way so if anyone can explain me where i'm doing something wrong.
My code :
void display_vector(std::vector<int>& to_display);
int main()
{
std::vector<int> vector_to_sort = { 2,6,7,2,1,80,2,59,8,9 };
display_vector(vector_to_sort);
}
void display_vector(std::vector<int> &to_display)
{
for (int i = 0; i < to_display.size(); i++)
{
std::cout << to_display[i] << ', ';
}
std::cout << '\n';
}
The solution i found on internet :
#include <iterator>
void display_vector(const vector<int> &v)
{
std::copy(v.begin(), v.end(),
std::ostream_iterator<int>(std::cout, " "));
}
Output of my code :
21129661129671129621129611129680112962112965911296811296911296
You use ", " instead of ', '.
You can use any of the following print mechanism in the display() function:
void display_vector(std::vector<int> &to_display)
{
//by using Normal for loop
for (auto i = to_display.begin(); i != to_display.end(); ++i) {
cout << *i << " ";
}
cout << endl;
//by using Range based for loop
for (int & i : to_display) {
cout << i << " ";
}
std::cout << '\n';
}
In this statement
std::cout << to_display[i] << ', ';
^^^^^^
you are using a multybyte character literal that has an implementation defined value.
Substitute it for string literal ", ".
As for the function then for starters if the vector is not being changed in the function then the parameter should be a constant reference.
You can use the range-based for loop to outfput elements of the vector like for example
#include <iostream>
#include <vector>
std::ostream & display_vector( const std::vector<int> &to_display, std::ostream &os = std::cout );
int main()
{
std::vector<int> vector_to_sort = { 2,6,7,2,1,80,2,59,8,9 };
display_vector(vector_to_sort) << '\n';
}
std::ostream & display_vector( const std::vector<int> &to_display, std::ostream &os )
{
for ( const auto &item : to_display )
{
os << item << ", ";
}
return os;
}
Using such a function you can for example output the vector in a text file.
Just replace below line
std::cout << to_display[i] << ', ';
with
std::cout << to_display[i] << ", ";
Also note that if you just want to display vector in function then declare parameter as const reference as shown below
void display_vector(const std::vector<int> &to_display);
The debuggers make it easy to examine vectors but I include a simple template to print out vectors of standard types and often use it when debugging data that I wish to look at with other tools.
template<class T>
void print(const std::vector<T>& v){
for (auto x: v)
std::cout << x << std::endl;
}

How sort double vector according to changes in first vector?

I would like to implement something like DoubleVector.
In this class I would also like to implement sort method, which sort v1_ and according to changes in v1_ the order in v2_ will also change.
The code is below:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class DoubleVector
{
vector<int> v1_;
vector<char> v2_;
public:
void sort()
{
//sort v1_ and also change order in v2_ according to changes in v1_
std::sort(v1_.begin(), v1_.end() /*, lambda ?*/);
}
void add(int value_v1, char value_v2)
{
v1_.push_back(value_v1);
v2_.push_back(value_v2);
}
void print()
{
const auto size = v1_.size();
for (size_t i=0;i<size;++i)
{
cout << v1_[i] << " " << v2_[i] << endl;
}
}
};
int main()
{
DoubleVector dv;
dv.add(6, 'g');
dv.add(2, 'r');
dv.add(3, 'y');
dv.add(4, 'a');
cout << "Before sort:" << endl;
dv.print();
dv.sort();
cout << "After sort:" << endl;
dv.print();//the values in v2_ are in the same order they don't change order according to v1_ changes
return 0;
}
As you can see DoubleVector before sort contains:
6 g
2 r
3 y
4 a
And after sort contains:
2 g
3 r
4 y
6 a
I would like to get:
2 r
3 y
4 a
6 g
So the first vector v1_ has been sorted, but the second still has got the same order and I would like to change order of elements in second v2_ vector according to changes in v1_.
I can write it, but I would like to do it in a fast and clean way, maybe using lambda as third argument in std::sort function? Vectors v1_ and v2_ in class DoubleVector must stay as they are.
Thank you very much.
Make a vector of std::pair<int,char> instead. Since operator < on the pair compares first and decides ties on the second, sorting std::vector<std::pair<int,char>> will produce the exact effect that you want:
vector<pair<int,char>> v;
v.push_back(make_pair(6, 'g'));
v.push_back(make_pair(2, 'r'));
v.push_back(make_pair(3, 'y'));
v.push_back(make_pair(4, 'a'));
sort(v.begin(), v.end());
for (int i = 0 ; i != v.size() ; i++) {
cout << v[i].first << " " << v[i].second << endl;
}
Demo.
You can do something like this:-
vector< pair<int,char> >v;
//do what you want
sort(v.begin(),v.end())
The sort function by default sorts according to first value but you can always define according to which criteria should the sort work
C++ STL - How does the third argument of the STL sort() work?
Try the following.
The way it works is to sort the position key pair based on the int vector value only and then use this ordering to extract values.
#include <iostream>
#include <algorithm>
#include <vector>
class dv
{
std::vector<int> _v1;
std::vector<char> _v2;
std::vector<std::pair<int, int> > _order;
public:
inline bool operator() (const std::pair<int, int>& v1_index_1,
const std::pair<int, int>& v1_index_2) const {
return _v1[v1_index_1.first] < _v1[v1_index_2.first];
}
void sort() {
std::sort(_order.begin(), _order.end(), *this);
}
void add(int value_v1, char value_v2) {
_order.push_back(std::pair<int, int>(_v1.size(), _v2.size()));
_v1.push_back(value_v1);
_v2.push_back(value_v2);
}
void print() {
const auto size(_v1.size());
for (size_t i=0; i<size; ++i) {
std::cout << _v1[_order[i].first]
<< " "
<< _v2[_order[i].second]
<< std::endl;
}
}
};
int main() {
dv dv;
dv.add(6, 'g');
dv.add(2, 'r');
dv.add(3, 'y');
dv.add(4, 'a');
std::cout << "before sort: " << std::endl;
dv.print();
std::cout << "sorting: " << std::endl;
dv.sort();
std::cout << "after sort: " << std::endl;
dv.print();
return 0;
}

pretty printing nested vectors

I have the following code to pretty-print generic vectors -:
// print a vector
template<typename T1>
std::ostream& operator <<( std::ostream& out, const std::vector<T1>& object )
{
out << "[";
if ( !object.empty() )
{
std::copy( object.begin(), --object.end(), std::ostream_iterator<T1>( out, ", " ) );
out << *--object.end(); // print the last element separately to avoid the extra characters following it.
}
out << "]";
return out;
}
I am getting a compiler error if I try to print a nested vector from it.
int main()
{
vector<vector<int> > a;
vector<int> b;
// cout << b ; // Works fine for this
cout << a; // Compiler error
}
I am using GCC 4.9.2 with the -std=c++14 flag.
The error message given by the compiler is -:
no match for 'operator<<' (operand types are
'std::ostream_iterator<std::vector<int>, char, std::char_traits<char>::ostream_type {aka std::basic_ostream<char>}' and 'const std::vector<int>')
std::copy( object.begin(), --object.end(), std::ostream_iterator<T1>( out, ", " ) );
You are using copy to ostream iterator which is not defined for vector of std::vector<>. One work around is to implement operator << in terms of operator << of children.
if ( !object.empty() )
{
//std::copy( object.begin(), --object.end(), std::ostream_iterator<T1>( out, ", " ) );
for(typename std::vector<T1>::const_iterator t = object.begin(); t != object.end() - 1; ++t) {
out << *t << ", ";
}
out << *--object.end(); // print the last element separately to avoid the extra characters following it.
}
Live example here
This method will not work for the same reason for std::vector<my_type> if opeartor << is not defined for class my_type
Just using a normal forloop instead of std::copy would solve this issue. As #Mohit suggested, the ostream iterator is not defined for nested vectors.
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;
// print a vector
template<typename T1>
std::ostream& operator <<( std::ostream& out, const std::vector<T1>& object )
{
out << "[";
if ( !object.empty() )
{
for(typename std::vector<T1>::const_iterator
iter = object.begin();
iter != --object.end();
++iter) {
out << *iter << ", ";
}
out << *--object.end();
}
out << "]";
return out;
}
int main() {
std::vector<std::vector<int> > a;
std::vector<int> b;
b.push_back(1);
b.push_back(2);
std::vector<int> c;
c.push_back(3);
c.push_back(4);
std::cout << b << std::endl;
std::cout << c << std::endl;
a.push_back(b);
a.push_back(c);
cout << a; // Compiler error
return 0;
}
Output would look like this:
[1, 2]
[3, 4]
[[1, 2], [3, 4]]