Я пытаюсь прочитать двоичный файл со строками и целыми числами и распечатать целые числа, соответствующие строке

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

jcake 567 сгренон 17

я пытаюсь получить числа после имени и распечатать их в iostream. Я понимаю, как читать int, потому что обычно 4 байта. Я просто никогда не читаю бинарный файл со строками.

while (readfile.good())
{

    char*buffer = new char[100];
    readfile.read(buffer, 100);
    if (readfile.eof())
    {
        delete[] buffer;
        break;
    }

    cout << buffer << endl;

person Community    schedule 05.02.2017    source источник
comment
Обычно длину данных переменной длины хранят в двоичных файлах. Это переменная длина или фиксированная длина? У вас есть спецификация формата?   -  person Retired Ninja    schedule 06.02.2017
comment
Вы не можете написать программу для чтения файла, не имея спецификации формата файла в качестве ссылки. У вас есть такая спецификация?   -  person Dai    schedule 06.02.2017
comment
Формат файла такой: jdow 567/n sgren 7654 имя и номер, каждый в отдельной строке.   -  person    schedule 06.02.2017
comment
Файл, который вы описали, является текстовым файлом. Что заставляет вас думать, что это двоичный код?   -  person Retired Ninja    schedule 06.02.2017
comment
потому что это файл .dat   -  person    schedule 06.02.2017
comment
Расширения не имеют значения, важно содержимое файла.   -  person Retired Ninja    schedule 06.02.2017


Ответы (1)


Существует множество различных способов сериализации строк в двоичных файлах. Наиболее распространенные способы:

  1. Последовательность байтов с префиксом длины, длина сохраняется как целочисленное значение и обычно составляет 1, 2 или 4 байта, за которыми следуют сами данные, например. 0x04 0x46 0x4F 0x4F 0x44 (0x04 = 4 байта, 46,4F,4F,44 == "FOOD"). Поскольку длина объявлена, нет необходимости в дозорном маркере, это также позволяет использовать нулевые байты в строке. 1.1. Иногда используется целое число переменной длины, но это продвинутый метод.
  2. Используется значение сигнального маркера, обычно символ NULL '\0', например. 0x46 0x4F 0x4F 0x44 0x00.
  3. Или формат файла указывает, что строка имеет фиксированную длину, и в этом случае не требуется ни внутриполосного объявления длины, ни дозорного, хотя иногда в спецификации будет сказано, что если фактическая длина строки меньше фиксированной длины, то null '\0' байт можно использовать в качестве прокладки.

В вашем вопросе не упоминалась какая-либо спецификация, которая подсказывала бы, какой формат вы используете.

Обратите внимание, что если вы просто хотите прочитать весь файл в память, вы должны использовать файл с отображением памяти для повышения производительности, хотя для этого требуется поддержка платформы. Вы можете сделать это с помощью Boost: http://www.boost.org/doc/libs/1_50_0/libs/iostreams/doc/classes/mapped_file.html

Если вы все еще хотите загрузить файл в буфер, вам нужно выделить достаточно большой буфер, чтобы вместить файл, вы не захотите использовать статически выделенный буфер (new char[100], потому что это неэффективно, если файл меньше 100 байт). большой и слишком маленький, если он больше 100 байт.

Если вы используете ifstream, используйте метод tellg(), чтобы получить длину файла, а затем выделите для него буфер:

using namespace std;

// ...

ifstream in( fileName, ifstream::ate | ifstream::binary );
streamsize length = in.tellg();
if( length <= 0 ) throw ...

size_t bufferLength = static_cast<size_t>( length );
char* buffer = new char[ bufferLength ];

in.read( buffer, bufferLength );

// do stuff with `buffer`

delete[] buffer;
person Dai    schedule 05.02.2017
comment
СПАСИБО ВАМ ОГРОМНОЕ!!! Я должен был знать, что нужно использовать команду tell and seek для получения длины файла. Я ценю это .. Я проголосовал за вас, но у меня недостаточно представителей, чтобы это показать = * ( - person ; 06.02.2017