std::istream_iterator Заставить читать строками
От: alexsy Россия  
Дата: 09.12.09 04:30
Оценка:
Всем здравствуйте..
есть файл типа:

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

Может есть у кого какой опыт в этом.
Re: std::istream_iterator Заставить читать строками
От: jazzer Россия Skype: enerjazzer
Дата: 09.12.09 05:08
Оценка:
Здравствуйте, 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 >.

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: std::istream_iterator Заставить читать строками
От: igna Россия  
Дата: 09.12.09 07:38
Оценка:
Здравствуйте, 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"));
}
Re[2]: std::istream_iterator Заставить читать строками
От: igna Россия  
Дата: 09.12.09 07:45
Оценка:
Как вариант:

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_)) {}
};


Смотря что тебе надо.
Re: std::istream_iterator Заставить читать строками
От: XuMuK Россия  
Дата: 09.12.09 14:24
Оценка:
Здравствуйте, 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"));
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.