// Vector elements consist of file items separated by space
std::vector<std::string> text;
std::copy(is_string, end_of_stream, std::inserter(text, text.begin()));
Can we populate the vector 'text' with file items separated by ' \r' or '\n'
using 'std::istream_iterator' as opposed to looping on getline()?
Mario Contestabile
Mar...@Computer.Org
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
> std::ifstream infile("1.txt");
> std::istream_iterator<std::string> is_string(infile);
> std::istream_iterator<std::string> end_of_stream;
>
> // Vector elements consist of file items separated by space
> std::vector<std::string> text;
> std::copy(is_string, end_of_stream, std::inserter(text, text.begin()));
>
> Can we populate the vector 'text' with file items separated by ' \r' or '\n'
> using 'std::istream_iterator' as opposed to looping on getline()?
Only if each string is on a different line. The istream_iterator just
uses operator >> on the string. So any whitespace is a string delimeter
in that context.
-Howard
Thus, it is possible to read lines using string's 'operator>>()'.
However, this requires a non-intuitive definition of whitespace, namely
one where spaces are not considered to be whitespaces. This can be
achieved by using a special 'std::ctype<char>' facet for the 'locale'
object of the corresponding stream. Here is some sample code doing just
this:
#include <locale>
#include <algorithm>
#include <iostream>
#include <string>
class whitespace_ctype: public std::ctype<char>
{
public:
whitespace_ctype(): std::ctype<char>(get_table()) {}
private:
static std::ctype_base::mask* get_table() {
static std::ctype_base::mask rc[table_size];
std::copy(classic_table(), classic_table() + table_size, rc);
rc[' '] &= ~ std::ctype_base::space;
return rc;
}
};
int main() {
std::locale l;
std::locale new_l(l, new whitespace_ctype);
std::cin.imbue(new_l);
std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n"));
}
I remember that I was recently accused of having a sneaky mindset in a
similar context (changing the "comma" into a different character to
separate the two members when formatting a 'complex' member). Probably
this accusation is right... :-)
Note, that the use of the space character in the above snippet is not
exactly standard conforming: If the character type is signed and the
space character is represented by a negative value, the above code
results in undefined behavior. However, this is not the case with any
character encoding I know...
--
<mailto:dietma...@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
Sent via Deja.com http://www.deja.com/
Before you buy.
Section 2.2 [lex.charset] requires the character values of all members
of the basic source character set (which includes space) to be positive.
--
Ross Smith <ros...@ihug.co.nz> The Internet Group, Auckland, New Zealand
========================================================================
"There are many technical details that make Linux attractive to the
sort of people to whom technical details are attractive." -- Suck
I wasn't aware of this restriction. So, the code I posted is portable
across all standard conforming implementations. This is great :-)
Thanks for the pointing this out.
--
<mailto:dietma...@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
Sent via Deja.com http://www.deja.com/
Before you buy.
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]