Всем здравствуйте..
есть файл типа:
petrov ivan ivanovich
sidoriv denis petrovich
. . . . . .
хочу считать данные из этого файла с помощью std::istream_iterator.
Проблема заключается в том что чтение производится не по строкам а по элементам
тоесть код:
std::copy( std::istream_iterator< std::string >( infile ), std::istream_iterator< std::string >(),
std::ostream_iterator< std::string >( std::cout, "\n" ) );
выводит так:
petrov
ivan
ivanovich
sidoriv
denis
petrovich
А хотелось бы вот так
petrov ivan ivanovich
sidoriv denis petrovich
Может есть у кого какой опыт в этом.
Здравствуйте, alexsy, Вы писали:
A>хочу считать данные из этого файла с помощью std::istream_iterator.
A>Проблема заключается в том что чтение производится не по строкам а по элементам
С помощью std::istream_iterator< std::string > у тебя это не получится, потому что он использует operator>>(std::istream& is, std::string& s), который читает поток только до ближайшего пробела, а тебе нужно, чтоб звался getline, который читает строку целиком.
Можно это (и другие аналогичные вещи) сделать при помощи такого трюка:
struct my_string : std::string {};
std::istream& operator>>(std::istream& is, my_string& s)
{
return getline(is, s);
}
int main()
{
std::copy( std::istream_iterator< my_string >( infile ),
std::istream_iterator< my_string >(),
std::ostream_iterator< std::string >( std::cout, "\n" ) );
}
my_string неявно приводится к std::string (публичная база), так что его можно использовать везде, где требуется std::string (кроме полиморфного создания/удаления, естественно, ибо у std::string нет виртуального деструктора), например, отдавать его в std::ostream_iterator< std::string >.
Здравствуйте, alexsy, Вы писали:
A>А хотелось бы вот так
A>petrov ivan ivanovich
A>sidoriv denis petrovich
#include <algorithm>
#include <cstring>
#include <iostream>
#include <iterator>
#include <locale>
#include <string>
using namespace std;
class ctype_newline_only_ws : public ctype<char> {
mask table_[table_size];
void init_table()
{
memcpy(table_, classic_table(), sizeof table_);
table_[' '] &= ~space;
table_['\f'] &= ~space;
table_['\r'] &= ~space;
table_['\t'] &= ~space;
table_['\v'] &= ~space;
}
public:
ctype_newline_only_ws() : ctype<char>((init_table(), table_)) {}
};
int main()
{
locale loc(locale(), new ctype_newline_only_ws);
cin.imbue(loc);
copy(
istream_iterator<string>(cin),
istream_iterator<string>(),
ostream_iterator<string>(cout, "\n"));
}
Как вариант:
class ctype_space_is_not_whitespace: public ctype<char> {
mask table_[table_size];
void init_table()
{
memcpy(table_, classic_table(), sizeof table_);
table_[' '] &= ~space;
}
public:
ctype_space_is_not_whitespace() : ctype<char>((init_table(), table_)) {}
};
Смотря что тебе надо.
Здравствуйте, alexsy, Вы писали:
A>Всем здравствуйте..
A>есть файл типа:
A>petrov ivan ivanovich
A>sidoriv denis petrovich
A>. . . . . .
A>хочу считать данные из этого файла с помощью std::istream_iterator.
A>Проблема заключается в том что чтение производится не по строкам а по элементам
в istream_iterator никогда не попадет '\n', т.к. он использует форматированный ввод, но можно использовать istreambuf_iterator и буст:
boost::char_separator<char> s("\n");
std::copy( boost::make_token_iterator<std::string>(std::istreambuf_iterator<char>(infile), std::istreambuf_iterator<char>(), s)
, boost::make_token_iterator<std::string>(std::istreambuf_iterator<char>(), std::istreambuf_iterator<char>(), s)
, std::ostream_iterator<std::string>(std::cout, "\n"));