std::ifstream и std::ios_base::binary
От: Аноним  
Дата: 22.07.08 05:41
Оценка:
Здравствуйте!

Есть 2 проблемы с побайтовым чтением бинарного файла при помощи std::ifstream
Следующий код выдает при чтении бинарного файла с содержимым 0x0D 0x0A 0x0D 0x0A следующее
#0 ... 0x0a ... good ? true ... 0/2
#1 ... 0x0a ... good ? true ... 2/4
#2 ... 0x00 ... good ? false ... 4/-1

а при при чтении бинарного файла с содержимым 0x01 0x02 0x03 0x04 следующее
#0 ... 0x01 ... good ? true ... 0/1
#1 ... 0x02 ... good ? true ... 1/2
#2 ... 0x03 ... good ? true ... 2/3
#3 ... 0x04 ... good ? true ... 3/4
#4 ... 0x00 ... good ? false ... 4/-1


Вопрос 1. Как заставить ifstream правильно читать последовательности CR/LF
Вопрос 2. Как правильно смотреть состояние бинарного потока std::ifstream, чтобы не было чтения "несуществующего байта" ?

Заранее благодарен за ответы.

#include <iostream>
#include <fstream>
#include <iomanip>

int main ( int argc, char **argv ) {

    if ( 2 != argc ) {
        std::cout << "Usage : " << argv[0] << std::endl;
        return 1;
    }

    std::ifstream in ( argv[1], std::ios_base::in, std::ios_base::binary );
    if ( !in.is_open() ) {
        std::cout << "Failed to open : " << argv[1] << std::endl;
        return 2;
    }

    int i = 0;
    while ( in.good() ) {
        char data = 0;

        std::fstream::pos_type previous_pos = in.tellg();
        in.read ( & data, sizeof ( char ) );
        std::fstream::pos_type current_pos = in.tellg();

        std::cout 
            << "#" << i++ << " ... 0x" << std::hex << std::setw ( 2 ) << std::setfill('0') << static_cast <int> ( data )
            << " ... good ? " << std::boolalpha << in.good() << " ... " << std::dec << previous_pos << "/" << current_pos << std::endl;
    }

    in.close();
    return 0;
}
ifstream binary чтение
Re: std::ifstream и std::ios_base::binary
От: Bell Россия  
Дата: 22.07.08 07:31
Оценка:
Здравствуйте, Аноним, Вы писали:

...

А>Вопрос 1. Как заставить ifstream правильно читать последовательности CR/LF

Для начала попробуй заменить
std::ifstream in ( argv[1], std::ios_base::in, std::ios_base::binary );

на
std::ifstream in ( argv[1], std::ios_base::in | std::ios_base::binary );


А>Вопрос 2. Как правильно смотреть состояние бинарного потока std::ifstream, чтобы не было чтения "несуществующего байта" ?

Состояние потока меняется после попытки чтения.
Любите книгу — источник знаний (с) М.Горький
Re[2]: std::ifstream и std::ios_base::binary
От: Аноним  
Дата: 22.07.08 08:01
Оценка:
B>Для начала попробуй заменить
B>
std::ifstream in ( argv[1], std::ios_base::in, std::ios_base::binary );

B>на
B>std::ifstream in ( argv[1], std::ios_base::in | std::ios_base::binary );



АААааааааааааа, спасибо! Слона-то я и не приметил
оператор , — зло
Re[3]: ой, что-то я совсем затупил ... (+)
От: Аноним  
Дата: 22.07.08 08:10
Оценка:
оператор запятая тут не виноват — нашелся конструктор с 3-мя параметрами.
Re[3]: std::ifstream и std::ios_base::binary
От: Roman Odaisky Украина  
Дата: 22.07.08 08:12
Оценка:
Здравствуйте, Аноним, Вы писали:

B>>Для начала попробуй заменить

B>>std::ifstream in ( argv[1], std::ios_base::in, std::ios_base::binary );
B>>на
B>>std::ifstream in ( argv[1], std::ios_base::in | std::ios_base::binary );

А>оператор , — зло :maniac:


А это не оператор «,». Он не работает в аргументах функции (без дополнительных скобок вроде f(x, (y, z))). Это какой-то левый конструктор в реализации твоего компилятора. Стандарт очень ясно говорит:
// 27.8.1.6 Constructors:
basic_ifstream();
explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);

Трехаргументного конструктора там нигде нет.
До последнего не верил в пирамиду Лебедева.
Re[4]: трехаргументный ctor вроде есть ...
От: Аноним  
Дата: 22.07.08 08:18
Оценка:
RO>Трехаргументного конструктора там нигде нет.

MSVC 7.1 Нашлось вот такое:

typedef basic_ifstream<char, char_traits<char> > ifstream;
explicit basic_ifstream(const char *_Filename, ios_base::openmode _Mode = ios_base::in, int _Prot = (int)ios_base::_Openprot);
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.