C ++:将读取的二进制文件存储到缓冲区中

问题描述 投票:5回答:4

我正在尝试读取二进制文件并将其存储在缓冲区中。问题是,在二进制文件中是多个以空字符结尾的字符,但它们不在最后,而是在其他二进制文本之前,所以如果我将文本存储在'\ 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;
    }
c++ buffer fgets null-terminated
4个回答
8
投票

我只想提一下,有一种从二进制文件读入缓冲区的标准方法。

使用<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;
}

2
投票

问题是你的缓冲区的写法,因为你一次读取一个字节。

如果你知道缓冲区中数据的长度,你可以强制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 

1
投票

我相信你的问题不在于阅读数据,而在于你如何尝试打印数据。

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

您向我们展示的示例打印一个C字符串。由于C-string是以'\ 0'结尾的字符序列,因此打印功能在第一个空字符处停止。这是因为你需要通过使用特殊的终止字符(比如这里的“\ 0”)或知道它的长度来知道字符串的结束位置。

因此,要打印整个数据,您必须知道它的长度并使用类似于您用于读取它的循环。


0
投票

你在Windows上吗?如果是这样,你需要执行_setmode(_fileno(stdout), _O_BINARY);

包括<fcntl.h><io.h>

© www.soinside.com 2019 - 2024. All rights reserved.