2017-01-04 10 views
3

Я пытаюсь прочитать номер unsigned long из двоичного файла.
я делаю это таким образом:read unsigned long из двоичного файла

infile.open("file.bin", std::ios::in | std::ios::binary); 
    char* U=new char[sizeof(unsigned long)]; 
    unsigned long out=0; 
    infile.read(U, sizeof(unsigned long)); 
    out=static_cast<unsigned long>(*U); 
    delete[] U; 
    U=NULL; 
    infile.close(); 

, но результат не является правильным.
Мои данные 6A F2 6B 58 00 00 00 00 ведьмой следует читать как 1483469418 но вне есть 106 в моем коде, который только первый байт данных

В чем проблема?
как я должен правильно прочитать unsigned long из файла?

+0

Какой формат младшему вы ожидаете, и какой формат вы используете? Это очень важно знать при работе с многобайтовыми целочисленными значениями. – tadman

+0

Вы просто забрасываете первый байт в unsigned long. Кроме того, метод не переносится в любом случае из-за конечной цели. –

+0

@tadman: как файл, так и система LE – RYN

ответ

3

Это потому, что вы производите разыменованное значение. То есть только char не полный 4 байта. *U является 106.

Вы можете прочитать данные без промежуточного буфера:

infile.read(reinterpret_cast<char*>(&out), sizeof out);

Разница заключается в том, что здесь вы переосмысление указателя, а не значение под ним.

Если вы все еще хотите использовать буфер, это должно быть *reinterpret_cast<unsigned long*>(U);, это также переинтерпретирует указатель 1-го, а затем разыгрывает его. Ключ состоит в разыменовании указателя правильного типа. Тип указателя определяет, сколько байтов используется для значения.

+0

Любая причина, по которой используется новый/неправильный тип буфера? Почему бы просто не передать это значение, которое оно уже ожидает? Endianess, по крайней мере, пугает меня этим ... –

+0

Боюсь, я не совсем понимаю вас. Использование буфера не является неправильным, я этого не говорил.Это лишнее в случае OPs, поэтому я фактически привел пример, который сохраняет значение непосредственно в переменной. Но если вы хотите использовать буфер, есть второй вариант, который я дал. Можно поменять байты до приведения, если это необходимо, но OP, похоже, не заботится об энтиансе. – luk32

+0

Ah crap - мой плохой .. Не видел, что было определено как - продолжайте тогда :) –

2

из = static_cast (U); должен быть вне = (без знака long *) (U);

Это может быть гораздо проще:

infile.open("file.bin", std::ios::in | std::ios::binary); 
unsigned long out=0; 
infile.read((char *)&out, sizeof(out)); 
infile.close(); 
1

Вы должны знать, является ли файл (не программа) большой байтов или обратным порядком байтов. Затем прочитать байты с fgetc() и reconsitute номер

так

unsigned long read32be(FILE *fp) 
    { 
     unsigned long ch0, ch1, ch2 ch3; 

     ch0 = fgetc(fp); 
     ch1 = fgetc(fp); 
     ch2 = fgetc(fp); 
     ch3 = fgetc(fp); 

     return (unsigned long) (ch0 << 24) | (ch1 << 16) | (ch2 << 8) | ch3 
    } 

Теперь он будет работать независимо от того, тоскует 32 бита или 64, big_endian или обратным порядком байтов. Если файл мало ориентирован, замените порядок fgetc() s.

Чтение двоичных файлов портативно удивительно сложно. Я поставил код на GitHub

https://github.com/MalcolmMcLean/ieee754

+0

Я собираюсь утверждать, что это c, а не C++, и это совсем не полезно. Предлагаете ли вы, чтобы OP заменила все процедуры ввода-вывода на c? Он не будет работать независимо от энтузиазма. Вам нужно вручную изменить порядок чтения. Вы можете сделать то же самое с кодом OPs. Просто используйте 'swap' в содержимом' U'. – luk32

+0

Он работает независимо от консистенции машины. Невозможно правильно проанализировать файл, независимо от его подлинности. –

+0

Исходный код также работает независимо от конечной цели машины. Призрачно отделять эти две вещи. Важно то, что машина/система vs file endianess. Если оба они одинаковы, проблем нет. Если они разные, вам нужно поменять байты. Так что да, можно правильно читать файл независимо от его энтиан. Вам нужно прочитать его на машине с той же энтузиазмом. Я хочу сказать, что невозможно сделать общий случай, и предлагая что-то работать независимо от энтианны без какой-либо условной замены байтов, является курит и экраны. Вы только что переместили проблему. – luk32

 Смежные вопросы

  • Нет связанных вопросов^_^