C ++: сохранить прочитанный двоичный файл в буфер

Я пытаюсь прочитать двоичный файл и сохранить его в буфере. Проблема в том, что в двоичном файле несколько символов с нулевым символом в конце, но они не в конце, а перед другим двоичным текстом, поэтому, если я сохраню текст после ‘\ 0’, он просто удалит его в буфер.

Пример:

char * a = "this is a\0 test";
cout << a;

Это будет просто вывод: this is a

вот мой реальный код:

эта функция читает один символ

bool CStream::Read  (int * _OutChar)
{
if (!bInitialized)
return false;

int iReturn = 0;

*_OutChar = fgetc (pFile);

if (*_OutChar == EOF)
return false;

return true;
}

И вот как я это использую:

    char * SendData = new char[4096 + 1];

for (i = 0; i < 4096; i++)
{
if (Stream.Read (&iChar))
SendData[i] = iChar;
else
break;
}

5

Решение

Я просто хочу упомянуть, что существует стандартный способ чтения из двоичного файла в буфер.

С помощью <cstdio>:

char buffer[BUFFERSIZE];

FILE * filp = fopen("filename.bin", "rb");
int bytes_read = fread(buffer, sizeof(char), BUFFERSIZE, filp);

С помощью <fstream>:

std::ifstream fin("filename.bin", ios::in | ios::binary );
fin.read(buffer, BUFFERSIZE);

То, что вы будете делать с буфером впоследствии, зависит от вас, конечно.

Изменить: полный пример с использованием <cstdio>

#include <cstdio>

const int BUFFERSIZE = 4096;

int main() {
const char * fname = "filename.bin";
FILE* filp = fopen(fname, "rb" );
if (!filp) { printf("Error: could not open file %s\n", fname); return -1; }

char * buffer = new char[BUFFERSIZE];
while ( (int bytes = fread(buffer, sizeof(char), BUFFERSIZE, filp)) > 0 ) {
// Do something with the bytes, first elements of buffer.
// For example, reversing the data and forget about it afterwards!
for (char *beg = buffer, *end=buffer + bytes; beg < end; beg++, end-- ) {
swap(*beg, *end);
}
}

// Done and close.
fclose(filp);

return 0;
}
8

Другие решения

Проблема, безусловно, заключается в записи вашего буфера, потому что вы читаете байт за раз.

Если вы знаете длину данных в вашем буфере, вы можете заставить cout продолжать:

char *bf = "Hello\0 world";
cout << bf << endl;
cout << string(bf, 12) << endl;

Это должно дать следующий вывод:

Hello
Hello  world

Однако это обходной путь, так как cout предназначен для вывода данных для печати. Имейте в виду, что вывод непечатаемых символов, таких как \ 0, зависит от системы.

Альтернативные решения:

Но если вы манипулируете двоичными данными, вы должны определить специальные структуры данных и печать. Вот несколько советов, с кратким описанием общих принципов:

struct Mybuff {   // special strtucture to manage buffers of binary data
static const int maxsz = 512;
int size;
char buffer[maxsz];
void set(char *src, int sz)  // binary copy of data of a given length
{ size = sz; memcpy(buffer, src, max(sz, maxsz)); }
} ;

Тогда вы можете перегрузить функцию оператора вывода:

ostream& operator<< (ostream& os, Mybuff &b)
{
for (int i = 0; i < b.size; i++)
os.put(isprint(b.buffer[i]) ? b.buffer[i]:'*');  // non printables replaced with *
return os;
}

И вы можете использовать это так:

char *bf = "Hello\0 world";
Mybuff my;
my.set(bf, 13);   // physical copy of memory
cout << my << endl;   // special output
2

Я считаю, что ваша проблема не в чтении данных, а в том, как вы пытаетесь их распечатать.

char * a = "this is a\0 test";
cout << a;

Этот пример, который вы показываете нам, печатает C-строку. Поскольку C-строка представляет собой последовательность символов, оканчивающихся на ‘\ 0’, функция печати останавливается на первом нулевом символе.
Это потому, что вам нужно знать, где заканчивается строка, либо используя специальный завершающий символ (например, \ 0 здесь), либо зная ее длину.

Таким образом, чтобы распечатать данные целиком, вы должны знать их длину и использовать цикл, аналогичный тому, который вы используете для чтения.

1

Вы на Windows? Если это так, вам нужно выполнить _setmode(_fileno(stdout), _O_BINARY);

Включают <fcntl.h> а также <io.h>

0
По вопросам рекламы [email protected]