Попробуйте это:
Он будет читать любой тип (который можно прочитать с помощью >>), разделенный любым символом (который вы выберете).
Примечание. После чтения объекта между объектом и разделителем должно быть только пространство. Таким образом, для таких вещей, как ObjectSepReader<std::string, ','>
, он будет читать список слов, разделенных ','.
Это упрощает использование наших стандартных алгоритмов:
#include <vector>
#include <sstream>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
std::stringstream data("1,2,3,4,5,6,7,8,9");
std::vector<int> vdata;
// Read the data from a stream
std::copy(std::istream_iterator<ObjectSepReader<int, ','> >(data),
std::istream_iterator<ObjectSepReader<int, ','> >(),
std::back_inserter(vdata)
);
// Copy data to output for testing
std::copy(vdata.begin(), vdata.end(), std::ostream_iterator<int>(std::cout," "));
}
Секретный класс, чтобы заставить его работать.
template<typename T,char S>
struct ObjectSepReader
{
T value;
operator T const&() const {return value;}
};
template<typename T,char S>
std::istream& operator>>(std::istream& stream, ObjectSepReader<T,S>& data)
{
char terminator;
std::string line;
std::getline(stream, line, S);
std::stringstream linestream(line + ':');
if (!(linestream >> data.value >> terminator) || (linestream.tellg() != line.size()+1) || (terminator != ':'))
{ stream.setstate(std::ios::badbit);
}
return stream;
}