LINUX.ORG.RU

чтение файла с помощью стандартной библиотеки


0

0

Когда я пишу:

int var1=0;

ifstream in("test", ios::in | ios::binary);

if(!in) {

...

}

in >> var1;

переменная var1 у меня возвращает "0".

Можно, конечно, через in.read((char*)&var1, sizeof(var1)), но порядок следования байт при считывании меня тоже не устраивает - значение переворачивается.

Как перегрузить оператор >> для целого и других типов?

Если нетрудно, приведите, пожалуйста, пример.


тебе нужно что-то типа fscanf? или тебе нужно считывать реальное 32-битное целое? in.read((char*)&var1, sizeof(var1)) - вроде должно работать, если в файле порядок следования баитов в слове такой же как и на машине, иначе нужно их переводить, так же как и в сетевом программировании (network to host short, host to network short), такие штики.

anonymous
()
Ответ на: комментарий от anonymous

не хотел бы "лабать" с помощью scanf.

У меня заказчик - "Козел". Договорились сначала, что буду писать на QT (я все писал через QDataStream s; s << ...; s >> ...), а теперь он вообще запел песню, что его программисты меня не поймут, т.к. пишут на VB 8-)и VC++(MFC). Поэтому я хотел бы если и переписывать, то с минимальной переделкой текста, да и зачем мне C, когда есть C++ 8-) ?

gtyrin
() автор топика

> Как перегрузить оператор >> для целого и других типов?

Не стоит этого делать.

Для работы с бинарными данными _нужно_ использовать fstream.read() && fstream.write().

Операторы << и >> служат для форматированного ввода / вывода в _текстовом_ представлении.

abbr
()
Ответ на: комментарий от gtyrin

а это жообще очень плохо использожать в ц++ функции из libc? мне почемуто кавется, что за этими fstream.read i write стоят обычные (::read, ::write), не так ли?

anonymous
()

> Как перегрузить оператор >> для целого и других типов?
> Если нетрудно, приведите, пожалуйста, пример.

Не трудно.
Для ввода/вывода новых типов определяют новый оператор << , для "подмены" существующего можно пойти по такому пути:
1. Определяем свою оболочку

template <class T> class Wrapper
{
    T value;
public:
    inline Wrapper(const T& val) { value = val; }
    inline Wrapper(const Wrapper& that) { value = that.value; }
    inline Wrapper& operator =(const T& val) { value = val; }
    inline Wrapper& operator =(const Wrapper& that) { value = that.value; }
    inline T& Value(void) { return value; }
    inline T Value(void) const { return value; }
    inline operator T() const { return value; }
    inline operator T&() { return value; }
};

2. Определяем операторы ввода/вывода для этой оболочки

template <class T> std::ostream& operator << (std::ostream& out, const Wrapper<T>& that)
{
    out << "<" << that.Value() << ">";
    return out;
}
template <class T> std::wostream& operator << (std::wostream& out, const Wrapper<T>& that)
{
    out << L"<" << that.Value() << L">";
    return out;
}
template <class T> std::istream& operator >> (std::istream& in, Wrapper<T>& that)
{
    in >> that.Value();
    return in;
}
template <class T> std::wistream& operator >> (std::wistream& in, Wrapper<T>& that)
{
    in >> that.Value();
    return in;
}


3. Используем

Wrapper<int>tst(13);
std::cin >> tst;
std::cout << tst << std::endl;

loki
()
Ответ на: комментарий от loki

>Не трудно.

Программисты, заканчивайте издеваться над программированием. Вы бы еще операторы языка переопределили Ж)

anonymous
()

Проверь флаги ошибок после in >> var1;
Наверняка у тебя или не число, или переполнение.
ios::in для ifstream лишнее.

sergio_nsk
()
Ответ на: комментарий от sergio_nsk

ifstream::rdstate() возвращает failbit - что бы это значило ?

А на счет переполнения не понял - откуда оно здесь может быть ?

gtyrin
() автор топика
Ответ на: комментарий от loki

попробовал...на консольных потоках действительно все работает (в литературе переопределение операторов для консоли встречаются 8-), а вот для файлового потока - облом :-((

gtyrin
() автор топика
Ответ на: комментарий от loki

в этот оберточный класс добавил:

template <class T> std::ifstream& operator >> (std::ifstream& in, Wrapper<T>& that)

{

in >> that.Value();

return in;

}

а в тестовой программе написал:

ifstream in(...)

...

in >> tst;

gtyrin
() автор топика
Ответ на: комментарий от gtyrin

Дерево наследования такое:

basic_istream
|____________
|            |
istream      basic_ifstream
             |
             ifstream

Поэтому проще было бы создать один оператор для общего предка - basic_istream:

template <class T, class C>
std::basic_istream<C, std::char_traits<C> >& operator >>  (std::basic_istream<C, std::char_traits<C> >& in, Wrapper<T>& val);

loki
()
Ответ на: комментарий от gtyrin

> ifstream::rdstate() возвращает failbit - что бы это значило?
Сейчас некогда искать, а сходу не скажу. Смотри Страуструпа.

> А на счет переполнения не понял - откуда оно здесь может быть ?
Переполнение не в смысле переполнения буфера, а в смысле выхода
за границы дапозона значений для int.

sergio_nsk
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.