<< и >> для двоичных потоков
От: Draconus  
Дата: 02.09.03 08:18
Оценка:
День добрый.
Подскажите пожалуйста, есть ли возможность делать ввод/вывод в двоичный (binary) поток через операторы << >>? Если можно, короткий пример вывода.
Заранее спасибо.
Дмитрий.
Re: << и >> для двоичных потоков
От: LaptevVV Россия  
Дата: 02.09.03 08:45
Оценка: 1 (1)
Здравствуйте, Draconus, Вы писали:

D>День добрый.

D>Подскажите пожалуйста, есть ли возможность делать ввод/вывод в двоичный (binary) поток через операторы << >>? Если можно, короткий пример вывода.
А зачем?
Используй read/write c первым аргументом (char *)&name.
long a;
from.read((char *)&a, sizeof(long));
to.write((char *)&a, sizeof(long));

И так для любого типа, который тебе нужен. В том числе и для новых.
Но если очень хочется, то надо перегрузить.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: << и >> для двоичных потоков
От: Draconus  
Дата: 02.09.03 09:06
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>А зачем?

LVV>Используй read/write c первым аргументом (char *)&name.
LVV>
LVV>long a;
LVV>from.read((char *)&a, sizeof(long));
LVV>to.write((char *)&a, sizeof(long));
LVV>

LVV>И так для любого типа, который тебе нужен. В том числе и для новых.
LVV>Но если очень хочется, то надо перегрузить.

Проблема вот в чем. Мне необходимо сохранять в двоичный файл данные из различных встроенных и custom-типов данных. При этом часто имеет место ситуация, когда один тип включает другой (например, класс, содержащий несколько массивов различных типов). Если делать вывод в обычный текстовый поток, можно переопределить операторы << для каждого из используемых классов, причем в классах содержащем, например, vector, использовать единожды переопределенный оператор << для vector. При этом я думал, что в зависимости от того, какой поток я открою (двоичный или текстовый), вывод автоматически будет идти в нужном виде.

У меня используется что-то вроде:

template<class _T>
ostream& operator<< (const ostream& _out, const vector<_T>& _vec)
{
   _out << _vec.size();
   for (vector<_T>::iterator it=_vec.begin(); it!=_vec.begin(); it++)
      _out << *it;
   return _out;
}

//....

ofstream out("file.dat", ios::binary);
vector<double> vec;
out << vec;


Так вот, вместо бинарного вывода получается обычный текстовый вывод.
Re[3]: << и >> для двоичных потоков
От: LaptevVV Россия  
Дата: 02.09.03 09:14
Оценка:
Здравствуйте, Draconus, Вы писали:

D>Здравствуйте, LaptevVV, Вы писали:


LVV>>А зачем?

LVV>>Используй read/write c первым аргументом (char *)&name.
LVV>>
LVV>>long a;
LVV>>from.read((char *)&a, sizeof(long));
LVV>>to.write((char *)&a, sizeof(long));
LVV>>

LVV>>И так для любого типа, который тебе нужен. В том числе и для новых.
LVV>>Но если очень хочется, то надо перегрузить.

D>Проблема вот в чем. Мне необходимо сохранять в двоичный файл данные из различных встроенных и custom-типов данных. При этом часто имеет место ситуация, когда один тип включает другой (например, класс, содержащий несколько массивов различных типов). Если делать вывод в обычный текстовый поток, можно переопределить операторы << для каждого из используемых классов, причем в классах содержащем, например, vector, использовать единожды переопределенный оператор << для vector. При этом я думал, что в зависимости от того, какой поток я открою (двоичный или текстовый), вывод автоматически будет идти в нужном виде.


D>У меня используется что-то вроде:


D>
D>template<class _T>
D>ostream& operator<< (const ostream& _out, const vector<_T>& _vec)
D>{
D>   _out << _vec.size();     // здесь можно ставить write
D>   for (vector<_T>::iterator it=_vec.begin(); it!=_vec.begin(); it++)
D>      _out << *it;          // и здесь можно ставить write
D>   return _out;
D>}
D>//....

D>ofstream out("file.dat", ios::binary);
D>vector<double> vec;
D>out << vec;
D>

Только не помню, как sizeof(T) сработает.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: << и >> для двоичных потоков
От: Draconus  
Дата: 02.09.03 09:23
Оценка:
Здравствуйте, LaptevVV, Вы писали:

D>>
D>>template<class _T>
D>>ostream& operator<< (const ostream& _out, const vector<_T>& _vec)
D>>{
D>>   _out << _vec.size();     // здесь можно ставить write
D>>   for (vector<_T>::iterator it=_vec.begin(); it!=_vec.begin(); it++)
D>>      _out << *it;          // и здесь можно ставить write
D>>   return _out;
D>>}
D>>//....

D>>ofstream out("file.dat", ios::binary);
D>>vector<double> vec;
D>>out << vec;
D>>

LVV>Только не помню, как sizeof(T) сработает.

а если, например, такое?

ofstream out("file.dat", ios::binary);
vector<vector<double> > matrix;
out << matrix;


тогда write просто выбросит в поток содержимое класса vector вместо данных которые он содержал.
Re[5]: << и >> для двоичных потоков
От: LaptevVV Россия  
Дата: 02.09.03 10:21
Оценка:
Здравствуйте, Draconus, Вы писали:

D>>>
D>>>template<class _T>
D>>>ostream& operator<< (const ostream& _out, const vector<_T>& _vec)
D>>>{
D>>>   _out << _vec.size();     // здесь можно ставить write
D>>>   for (vector<_T>::iterator it=_vec.begin(); it!=_vec.begin(); it++)
D>>>      _out << *it;          // и здесь можно ставить write
D>>>   return _out;
D>>>}
D>>>ofstream out("file.dat", ios::binary);
D>>>vector<double> vec;
D>>>out << vec;
D>>>

D>а если, например, такое?

D>
D>ofstream out("file.dat", ios::binary);
D>vector<vector<double> > matrix;
D>out << matrix;
D>


D>тогда write просто выбросит в поток содержимое класса vector вместо данных которые он содержал.

Так надо ж по-другому перегрузить! В двукратном цикле.
Или ты хочешь единственной перегрузкой обрабатывать все, что угодно????
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: << и >> для двоичных потоков
От: Кодт Россия  
Дата: 02.09.03 11:23
Оценка:
Здравствуйте, Draconus, Вы писали:

D>Подскажите пожалуйста, есть ли возможность делать ввод/вывод в двоичный (binary) поток через операторы << >>? Если можно, короткий пример вывода.


binary|text — это наследие юникса. Разница между ними — сюрприз! — в конвертации символов LF ('\n') <-> CR,LF ("\r\n") и использовании EOF ((char)26) как маркера конца файла.
И больше ни в чем!!!

ostream::operator <<(int n) — это то же самое, что fprintf(fp, "%d", n)

Если хочешь писать двоичные данные — пользуйся функциями двоичного ввода-вывода read()/write() (в голом Си им соответствуют fread(), fwrite()).
Перекуём баги на фичи!
Re[6]: << и >> для двоичных потоков
От: Draconus  
Дата: 02.09.03 11:47
Оценка:
Здравствуйте, LaptevVV, Вы писали:

D>>тогда write просто выбросит в поток содержимое класса vector вместо данных которые он содержал.

LVV>Так надо ж по-другому перегрузить! В двукратном цикле.
LVV>Или ты хочешь единственной перегрузкой обрабатывать все, что угодно????

в данном случае — не все что угодно, а любой вектор (в том числе и вектор векторов). А иначе какой смысл писать типизируемую операцию <<?
Re[7]: << и >> для двоичных потоков
От: Кодт Россия  
Дата: 02.09.03 11:59
Оценка:
Здравствуйте, Draconus, Вы писали:

D>Здравствуйте, LaptevVV, Вы писали:


D>>>тогда write просто выбросит в поток содержимое класса vector вместо данных которые он содержал.

LVV>>Так надо ж по-другому перегрузить! В двукратном цикле.
LVV>>Или ты хочешь единственной перегрузкой обрабатывать все, что угодно????

D>в данном случае — не все что угодно, а любой вектор (в том числе и вектор векторов). А иначе какой смысл писать типизируемую операцию <<?


// для любых итераторов
template<class FwdIt>
void dump(ostream& ostr, const FwdIt& iter, const FwdIt& end)
{
  std::copy(iter, end, ostream_iterator(ostr, ", "));
}

// для STL-контейнеров
template<class Cont>
void dump(ostream& ostr, const Cont& cont)
{
  dump(ostr, cont.begin(), cont.end();
}

template<class E>
ostream& operator << (ostream& ostr, std::vector<E> const& cont)
{
  dump(ostr, cont); return ostr;
}
template<class E>
ostream& operator << (ostream& ostr, std::list<E> const& cont)
{
  dump(ostr, cont); return ostr;
}
template<class E>
ostream& operator << (ostream& ostr, std::set<E> const& cont)
{
  dump(ostr, cont); return ostr;
}
template<class E>
ostream& operator << (ostream& ostr, std::deque<E> const& cont)
{
  dump(ostr, cont); return ostr;
}


Ы?
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.