Здравствуйте!
Есть 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;
}
Здравствуйте, Аноним, Вы писали:
...
А>Вопрос 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, чтобы не было чтения "несуществующего байта" ?
Состояние потока меняется
после попытки чтения.
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 );
АААааааааааааа, спасибо! Слона-то я и не приметил
оператор , — зло
Здравствуйте, Аноним, Вы писали:
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);
Трехаргументного конструктора там нигде нет.
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);