2016-02-06 6 views
1

Видимо этот кусок кода:Использование станд :: ifstream :: читать подсчитывать количество символов

std::ifstream filev(path, std::ios::binary|std::ios::in); 
unsigned long int nData = 0; 
filev.read((char*)&nData, sizeof(nData)); 

Как @IgorTandetnik предложил используется для подсчета количества байтов, присутствующих в бинарном файле, благодаря применению заголовок файла, в частности, в Windows в конце выполнения nData будет содержать размер файла.

Теперь мне интересно, почему этот код на одном процессоре дает разные результаты на разных языках S.O.

Может кто-нибудь дать мне объяснение, почему MSVC работает над этим кодом?

+1

'можно использовать ... для подсчета количества байтов. Нет, не совсем. Все, что он делает, читает первые 4 или 8 байтов из файла и интерпретирует их как представление целого числа. Возможно, что определенный формат файла, с которым вы работаете, состоит в том, чтобы хранить размер файла в первых нескольких байтах (или конкретный файл имеет первые байты, соответствующие размеру его файла по чистому совпадению), но это обычно не относится к произвольному файлу , –

+2

'unsigned long int' [32 бит большой для Windows и 64 бит в Linux] (https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models); поэтому один и тот же код извлекает разные значения из одного и того же файла на разных платформах (другими словами, ваш код не переносится). Я не понимаю, как вы можете получить значение «0x3e4fc7a8» в любом случае, учитывая данные, которые вы показываете; Я подозреваю, что вы ошибаетесь в этом отношении. Во всяком случае, используйте ['uint32_t' и др.] (Http://en.cppreference.com/w/cpp/types/integer), когда вам понадобятся целые числа определенного размера бит портативным способом. –

+0

спасибо за вашу помощь, вы правы, я отредактировал вопрос в соответствии с вашим предложением, если вы ответите на свои комментарии, я помечаю его как решение. – Luca

ответ

1

Это не имеет ничего общего с размером файла (возможно, что ваш файл хранит свой собственный размер в первых 4 байтах, но это не относится к произвольному файлу и в любом случае находится рядом с точкой) ,

Ваш код демонстрирует поведение, определяемое реализацией; другими словами, он не переносится. В частности, unsigned long int - 32 bit large on Windows and 64 bit on Linux, поэтому вы иногда читаете первые 4 байта файла и первые 8 байтов в другое время; естественно, это приводит к разным значениям, когда эти байты интерпретируются как двоичное представление целого числа.

Используйте unit32_t et al, когда вам понадобятся целые числа определенного размера бит.

Это все еще оставляет фактом, что двоичное представление целого является самим реализацией, даже если две реализации используют целые числа того же размера. Например, вы удивляетесь, если вы когда-либо запускаете этот код на платформе большого конца (к счастью, в наши дни это несколько реже) или тот, который не использует представление с двумя дополнениями (это практически не существует).

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