Resolved, thanks all. The vector needs to be initialized.
I am new in c++. I appreciate it if you cuold help me print the content of the following vector v. Here is the code:
#include <stdio.h>
#include <vector>
#include <iostream>
int main(int argc, char **argv)
{
std::cout << "hello world\n";
std::vector<int>* v; (<-- std::vector<int>* v = new std::vector<int>();]
v->push_back(17);
v->push_back(12);
v->push_back(23);
v->push_back(42);
for(std::vector<int>::iterator it = v->begin(); it!= v->end(); ++it) {
std::cout << *it << "\n";
}
std::cout <<"done\n";
return 0;
}
You missed to allocate memory for your vector pointer. I'd rather recommend just using a variable allocated on the stack:
#include <stdio.h>
#include <vector>
#include <iostream>
int main(int argc, char **argv)
{
std::cout << "hello world\n";
std::vector<int> v; // <<<<< Note that * was omitted here
v.push_back(17);
v.push_back(12);
v.push_back(23);
v.push_back(42);
for(std::vector<int>::iterator it = v.begin(); it!= v.end(); ++it) {
std::cout << *it << "\n";
}
std::cout <<"done\n";
return 0;
}
See the Live Demo.
As for your edit:
v will be used as follows:
void AddItem(uint64_t fkey, vector<uint64_t>* v) {
v->push_back(fkey);
}
Rather choose this signature:
void AddItem(uint64_t fkey, vector<uint64_t>& v) {
// ^ << Choose a reference
v.push_back(fkey);
// ^ << dereference accordingly
}
No need to make v a pointer here, use something like this instead:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main() {
std::vector<int> v;
// push_back data...
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout,","));
}
This will print out the contents of v from beginning to end separated by , chars.
If you really want to make v a pointer to a std::vector though, then try the following:
int main() {
std::vector<int>* v = new std::vector<int>(); // allocate memory on heap
v->push_back(17);
// etc...
std::copy(v->begin(), v->end(), std::ostream_iterator<int>(std::cout,","));
delete v; // make sure to delete from heap to prevent memory leak
}
I'm assuming this is not real code because there is no good reason to use a pointer to a vector in this case and the pointer doesn't point at anything.
But if your question is just how to print the contents of a vector given a pointer then you can simply dereference the pointer and use a range-based for loop.
#include <vector>
#include <iostream>
void print(std::vector<int>* v) {
for(int value : *v)
std::cout << value << "\n";
}
int main() {
std::cout << "hello world\n";
std::vector<int> v = {17, 12, 23, 42};
print(&v);
std::cout <<"done\n";
}
Live demo.
Related
Is there a way to delete an item in a set / map and get the former value as a temporary return value so that I can move() somewhere else ?
Yes, use .extract().
#include <iostream>
#include <memory>
#include <set>
int main()
{
using elem = std::unique_ptr<int>;
std::set<elem> set;
set.insert(std::make_unique<int>(1));
set.insert(std::make_unique<int>(2));
set.insert(std::make_unique<int>(3));
// auto iter = set.find(...);
auto iter = set.begin(); // Some iterator.
elem x = std::move(set.extract(iter).value());
std::cout << *x << "\n\n"; // 1
for (const auto &it : set)
std::cout << *it << '\n'; // 2 3
}
I'm using non-copyable std::unique_ptr<int> as the element type to demonstrate that no copies are being made.
A container stores pointers to integers. I would like to find integer=66 using normal variable.
When I am trying to do this by pointer it is ok.
Code:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main ()
{
int *a=new int(22);
int *b=new int(44);
int *c=new int(66);
int d = 66;
vector<int*> v1;
v1.push_back(a);
v1.push_back(b);
v1.push_back(c);
std::vector<int*>::iterator it;
// it = find (v1.begin(), v1.end(), c); // Ok.
it = find (v1.begin(), v1.end(), d);
if (it != v1.end())
{
std::cout << "Element found in myvector: " << **it << '\n';
}
else
{
std::cout << "Element not found in myvector\n";
}
return 0;
}
I was trying to use find_if() function.
You could use a lambda function like this:
std::find_if(
std::begin(pointer_vec), std::end(pointer_vec),
[](const int *p){return p != nullptr && *p == 66;});
In C++11 you can do this:
it = find_if (v1.begin(), v1.end(), [d](int* p){ return *p == d; });
I would like to know if there is an elegant way or a built-in function to convert vector<double> to vector<string>. What I've done is simple
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
std::vector<std::string> doubeVecToStr(const std::vector<double>& vec)
{
std::vector<std::string> tempStr;
for (unsigned int i(0); i < vec.size(); ++i){
std::ostringstream doubleStr;
doubleStr << vec[i];
tempStr.push_back(doubleStr.str());
}
return tempStr;
}
int main( int argc, char* argv[] )
{
std::vector<double> doubleVec;
doubleVec.push_back(1.0);
doubleVec.push_back(2.1);
doubleVec.push_back(3.2);
std::vector<std::string> doubleStr;
doubleStr = doubeVecToStr(doubleVec);
for (unsigned int i(0); i < doubleStr.size(); ++i)
std::cout << doubleStr[i] << " ";
std::cout << std::endl;
return 0;
}
There are many ways, but a standard solution is to use std::transform with a lambda using std::to_string for the conversion :
std::transform(std::begin(doubleVec),
std::end(doubleVec),
std::back_inserter(doubleStr),
[](double d) { return std::to_string(d); }
);
And you can wrap that in a function template to make it work with any Standard compliant container :
template<class IteratorIn, class IteratorOut>
void to_string(IteratorIn first, IteratorIn last, IteratorOut out)
{
std::transform(first, last, out,
[](typename std::iterator_traits<IteratorIn>::value_type d) { return std::to_string(d); } );
}
Or in C++14, with a generic lambda :
template<class IteratorIn, class IteratorOut>
void to_string(IteratorIn first, IteratorIn last, IteratorOut out)
{
std::transform(first, last, out, [](auto d) { return std::to_string(d); } );
}
And call it with any container (i.e. it works with std::list<int>, for instance) :
to_string(std::begin(doubleVec), std::end(doubleVec), std::back_inserter(doubleStr));
Notes :
If you don't have a C++11 compiler, write your own to_string function template :
Example:
template<class T>
std::string my_to_string(T v)
{
std::stringstream ss;
ss << v;
return ss.str();
}
And use it in a similar way :
std::transform(doubleVec.begin(),
doubleVec.end(),
std::back_inserter(doubleStr),
my_to_string<double> );
You should reserve() the memory in the output vector to avoid reallocations during std::transform() :
e.g. do this :
std::vector<std::string> stringVec;
stringVec.reserve(v.size()); // reserve space for v.size() elements
Live demo
Using copy and ostream_iterator:
#include <vector>
#include <iostream>
#include <sstream>
#include <iterator>
int main()
{
std::vector<double> numbers{1.0, 2.1, 3.2};
std::stringstream output;
std::copy(numbers.begin(), numbers.end(), std::ostream_iterator<double>(output, " "));
std::cout << output.str() << std::endl;
}
In general, if you have a container of T and want to create a container of U from the container of T, as others have mentioned the algorithm to look for is std::transform.
If you are not using C++ 11, Here is std::transform usage:
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <iterator>
#include <sstream>
std::string Transformer(double d)
{
std::ostringstream doubleStr;
doubleStr << d;
return doubleStr.str();
}
int main()
{
std::vector<double> doubleVec;
doubleVec.push_back(1.0);
doubleVec.push_back(2.1);
doubleVec.push_back(3.2);
std::vector<std::string> doubleStr;
std::transform(doubleVec.begin(), doubleVec.end(), std::back_inserter(doubleStr), Transformer);
std::copy(doubleStr.begin(), doubleStr.end(), std::ostream_iterator<std::string>(std::cout, " "));
}
Output:
1 2.1 3.2
I am trying to get an output of the number of all the identical strings in a vector as part of a much larger program. After a lot of research I have managed to put something together that works but it seems messy and I was wondering if there was a better way to do it.
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;
void setMap(string i);
void addMap(string i);
map<string, int> myMap;
int main()
{
vector<string> myVector;
string myArray[6]={"foo","foo","bar","roo","foo","bar"};
for (int i=0; i<6; i++)
{
myVector.push_back(myArray[i]);
}
for_each (myVector.begin(), myVector.end(), setMap);
for_each (myVector.begin(), myVector.end(), addMap);
for (map<string, int, less< string >>::const_iterator iter = myMap.begin();
iter != myMap.end(); ++iter )
cout <<iter->first<<'\t'<<iter->second<<endl;
return 0;
}
void setMap(string i)
{
myMap[i]=0;
}
void addMap(string i)
{
myMap[i]++;
}
This code works fine and gives me the output I was after but I'm not that keen on having to add 2 extra functions to make it work or having to make the map global. Any hints would be gratefully received.
Well the simplest way to not have the extra functions and not have the map as global would be to not use for_each.
for_each (myVector.begin(), myVector.end(), setMap);
for_each (myVector.begin(), myVector.end(), addMap);
becomes
map<string, int> myMap;
for (vector<string>::iterator i = myVector.begin(); i != myVector.end(); ++i)
myMap[*i]=0;
for (vector<string>::iterator i = myVector.begin(); i != myVector.end(); ++i)
++myMap[*i];
Once you done that you could also remove the first loop
map<string, int> myMap;
for (vector<string>::iterator i = myVector.begin(); i != myVector.end(); ++i)
++myMap[*i];
since the map values will be initialised to zero anyway.
What made you think you had to use for_each anyway?
Your setMap function is unnecessary.
Consider what this function does, should the map's key not be present.
void addMap(string i)
{
myMap[i]++;
}
The expression myMap[i] will add a new key to your map.
Since the value type is int, this new value will be int(), which is guaranteed to be 0.
What about this? Encapsulate the counting mechanism in a separate function for reusability.
// Iterator pair based interface
template <class Iterator>
std::map<typename Iterator::value_type,int>
count(Iterator begin, Iterator end) {
std::map<typename Iterator::value_type,int> counts;
for (Iterator i = begin; i != end; ++i)
counts[*i]++;
return counts;
}
// Sequence interface
template <class Sequence>
inline std::map<typename Sequence::value_type,int>
count(Sequence seq) {
return count(seq.begin(), seq.end());
}
Then simply use it like this:
// C++11
for (const auto & c : count(myVector))
cout << c->first << '\t' << c->second << endl;
// C++03
std::map<string,int> counts = count(myVector);
for (std::map<string,int>::const_iterator c = counts.begin(), e = counts.end(); c != e; ++c)
cout << c->first << '\t' << c->second << endl;
Simple demo
Under C++11, you can do this:
#include <string>
#include <unordered_map>
#include <iostream>
int main() {
std::string myArray[6] = {"foo","foo","bar","roo","foo","bar"};
std::unordered_map<std::string, size_t> m;
for (const auto& s : myArray)
++m[s];
for (const auto& p : m)
std::cout << p.first << "\t" << p.second << std::endl;
}
This prints:
foo 3
bar 2
roo 1
This works because m[s] will automatically insert s into m if not already there.
Using std::unordered_map (a hashtable) is likely to be cheaper than std::map (a balanced tree).
You can do something very similar under C++03, except the "for each" loops shown above would be replaced by the regular "for" loops.
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <map>
using namespace std;
int main (int argc, char * const argv[]) {
string myArray[]={"foo","foo","bar","roo","foo","bar"};
int arr_length = 6;
vector<string> myVector(myArray, myArray + arr_length);
//Print contents of vector:
copy(myVector.begin(),
myVector.end(),
ostream_iterator<string>(cout, " ")
);
cout << endl;
map<string, int> myMap;
vector<string>::iterator pos;
for (pos=myVector.begin(); pos<myVector.end(); ++pos)
{
myMap[*pos] += 1;
}
map<string, int>::iterator mapPos;
for (mapPos=myMap.begin(); mapPos != myMap.end(); ++mapPos) {
cout << "word: " << mapPos->first << "\t"
<< "count: " << mapPos->second << endl;
}
return 0;
}
--output:--
foo foo bar roo foo bar
word: bar count: 2
word: foo count: 3
word: roo count: 1
how can I store the values returned from a function to a string as comma seperated values. Can anyone help me..?
const myVector &vecList = obj.get_List();
vector<myNumVector *>::const_iterator iter;
for (iter= vecList.begin(); iter!= vecList.end(); iter++)
{
string myNum = (*iter)->get_myNum();
string myNumList = ?
//myNumList should be = drt123,ret34,dfghgd234.... if these are the return values
} //can we achive this by use of some sting functions..?
As can be seen from the links I posted, there are lots of ways to do this. Here is, I believe, the simplest:
#include <vector>
using std::vector;
#include <string>
using std::string;
#include <boost/assign/list_of.hpp>
using boost::assign::list_of;
namespace ba = boost::assign;
vector<string> victor = list_of
("Clarence Oveur")
("Roger Murdock")
("Victor Basta");
int main() {
string result;
for(vector<string>::iterator it = victor.begin();
it != victor.end();
++it) {
if(it != victor.begin()) {
result += ", ";
}
result += *it;
}
cout << result << "\n";
}
EDIT: To translate directly to OP's question:
const myVector &vecList = obj.get_List();
vector<myNumVector *>::const_iterator iter;
string myNumlist;
for (iter= vecList.begin(); iter!= vecList.end(); iter++)
{
string myNum = (*iter)->get_myNum();
if(iter!=vecList.begin()) {
nyNumList += ",";
}
myNumList += myNum;
}
EDIT: Simplified by removing bool first from previous solution.
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
int main () {
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
std::stringstream list;
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(list, ","));
std::cout << list.str();
return 0;
}
Outputs: 1,2,3,4,
more modern approach, also solving the trailing ","
#include <string>
#include <numeric>
#include <iostream>
int main() {
const auto v = {1, 2, 3, 4};
const auto list = std::accumulate(begin(v), end(v), std::string{}, [](const std::string& so_far, const auto& next) {
return so_far + (so_far.empty() ? "" : ", ") + std::to_string(next);
});
std::cout << list;
return 0;
}
Yes, this can be achieved using string functions, along with a handful other methods.
Given a string myNumList defined outside the loop, you could simply
myNumList += "," + myNum;
although that would add an extraneous comma in the beinning, so check if iter is pointing there first:
if(iter != vecList.begin())
myNumList += ',';
myNumList += myNum;