Boost logo

Boost :

From: Sean Wilson (smileyhamster_at_[hidden])
Date: 2002-03-21 15:10:22


Hi,

The standard library provides the istream_iterator which is used to iterate
over input streams. The following example extracts all the strings from a
file and adds them to a list:

int main()
{
  std::ifstream inputStream("test"));
  std::list<std::string> output;

  typedef std::istream_iterator<std::string> InputIterator;

  std::copy(InputIterator(inputStream),
            InputIterator(),
            std::back_inserter(output));
}

However, to my knowledge, there is no easy way to extract only a certain
number of elements. For example, just say you had a file which contained the
number of strings in a list, followed by those strings and then the same
again for another list (i.e. it would take multiple std::copy calls to
recreate all the lists). The only way I know of extracting this data would
be to use explicit loops because only the eof marker can be used as the end
of the sequence when copying using istream_iterator.

My proposal is for a istream_iterator that counts how many elements have
been extracted so far and then indicates the end of the sequence when all
the required elements have been extracted or a failure occurs.

The following is a unit test to see if counted_istream_iterator is
implemented correctly:

std::string sentence("The quick brown fox jumped over the lazy dog.");

const int NUM_INPUTS = 4;

std::list<std::string> getList1()
{
std::stringstream inputStream(sentence);
std::list<std::string> output;

typedef counted_istream_iterator<std::string> InputIterator;

std::copy(InputIterator(inputStream, NUM_INPUTS),
           InputIterator(),
           std::back_inserter(output));

return output;
}

std::list<std::string> getList2()
{
std::stringstream inputStream(sentence);
std::list<std::string> output;

for (int i = 0; i < NUM_INPUTS; ++i)
{
  std::string word;

  if (!(inputStream >> word))
   break;

  output.push_back(word);
}

return output;
}

int main()
{
assert(getList1() == getList2());

std::cout << "Test successful." << std::endl;

return 0;
}

Both lists should only contain {"The", "quick", "brown", "fox"}.

Would other people find this iterator useful? If so, I would be happy to
submit an implementation.

Regards,

Sean Wilson

_________________________________________________________________
Send and receive Hotmail on your mobile device: http://mobile.msn.com


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk