Reputation: 3613
I'm wondering what the best way to write from an std::stringstream
into a vector<int>
.
Here's an example of what's in the stringstream
:
"31 #00 532 53 803 33 534 23 37"
Here's what I've got:
int buffer = 0;
vector<int> analogueReadings;
stringstream output;
while(output >> buffer)
analogueReadings.push_back(buffer);
However what seems to happen is, it reads the first thing, then it gets to #00
and returns 0
because it's not a number.
Ideally, what I want is, it gets to a #
and then just skips all characters until the next whitespace. Is this possible with flags or something?
Thanks.
Upvotes: 4
Views: 12377
Reputation: 465
I think the best method would be to
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
string numbers = "23,24,27,28";
vector<int> integers;
stringstream s(numbers);
char ch;
int a;
while(s>>a>>ch) integers.push_back(a); //s >> reads int char pair
s>>a; // reads the last int
integers.push_back(a);
for(int i = 0; i < integers.size(); i++) cout << integers[i] << "\n";
}
Upvotes: 0
Reputation: 27038
You need to test if you got a number or not. use the answer from here:
How to determine if a string is a number with C++?
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
bool is_number(const std::string& s){
std::string::const_iterator it = s.begin();
while (it != s.end() && std::isdigit(*it)) ++it;
return !s.empty() && it == s.end();
}
int main ()
{
vector<int> analogueReadings;
std::istringstream output("31 #00 532 04hello 099 53 803 33 534 23 37");
std::string tmpbuff;
while(output >> tmpbuff){
if (is_number(tmpbuff)){
int num;
stringstream(tmpbuff)>>num;
analogueReadings.push_back(num);
}
}
}
the result is 31 532 99 53 803 33 534 23 37
Also, important drawbacks of using lexical casts like this is described here:
How to parse a string to an int in C++? , where an alternative to tringstream(tmpbuff)>>num
is given.
For example 04hello becomes 4 and 7.4e55 becomes 7. There are also terrible problems with underflow and underflow. The clean solution by André Caron converts
25 10000000000 77 0 0
into
25 0 0
on my system. Note that also 77 is missing!
Upvotes: 1
Reputation: 12670
No loops version:
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <sstream>
using namespace std;
class IntegerFiller
{
vector<int> &m_vec;
public:
IntegerFiller(vector<int> &vec): m_vec(vec) {}
void operator()(const std::string &str)
{
stringstream ss(str);
int n;
ss >> n;
if ( !ss.fail() )
m_vec.push_back(n);
}
};
int main()
{
vector<int> numbers;
IntegerFiller filler(numbers);
for_each(istream_iterator<string>(cin), istream_iterator<string>(), filler);
copy(numbers.begin(), numbers.end(), ostream_iterator<int>(cout, " "));
return 0;
}
Upvotes: 0
Reputation: 45244
#include <iostream>
#include <sstream>
#include <vector>
int main ( int, char ** )
{
std::istringstream reader("31 #00 532 53 803 33 534 23 37");
std::vector<int> numbers;
do
{
// read as many numbers as possible.
for (int number; reader >> number;) {
numbers.push_back(number);
}
// consume and discard token from stream.
if (reader.fail())
{
reader.clear();
std::string token;
reader >> token;
}
}
while (!reader.eof());
for (std::size_t i=0; i < numbers.size(); ++i) {
std::cout << numbers[i] << std::endl;
}
}
Upvotes: 6