1

我是一名 ac 程序员,试图在 C++ 中开始我生命的新阶段(我知道我仍在使用下面的 printf,但那是因为格式化很容易)。我希望从对象的成员函数中打印出数据文件的第一个字节。我认为我的流缓冲区在读取数据之前就被破坏了,但我不知道该怎么做。

我的课程如下所示

class MyParser {
    MyParser(string filepath);
    void readHeader();

    streambuf *pbuf;
    long size;
}

我的构造函数打开文件,取出缓冲区,输出第一个字节并返回。(我认为pbuf在这段代码的末尾会死)。此代码输出First Byte (in constructor): 0x8C

MyParser::MyParser(string filepath) {
    ifstream file(filepath.c_str(), ios::in | ios::binary)
    pbuf = file.rdbuf();
    size = pbuf->pubseekoff(0,ios::end,ios::in);
    pbuf->pubseekpos(0,ios::in);

    unsigned char byte = pbuf->sgetc();
    printf("First Byte (in constructor): 0x%02X\n", byte);

    return;
}

我的读取头正在转储第一个字节,但根据输出,所有看到的是First Byte (in readHeader): 0xFF

void MyParser::readHeader() {
    unsigned char byte = pbuf->sgetc();
    printf("First Byte (in readHeader): 0x%02X\n", byte);
}

我的 main 只是创建了一个解析器并尝试 readHeader

void main() {
    MyParser parser("../data/data.bin");
    parser.readHeader();
}

我认为我的问题的解决方案是创建一个new流缓冲区,但new streambuf(file.rdbuf())对我不起作用。有什么建议吗?

4

2 回答 2

1

您的程序具有未定义的行为:您保留的流缓冲区归std::ifstream您在构造函数主体中打开的所有。当这个对象死亡时,流缓冲区也会被释放。避免这个问题的最简单方法是让你std::ifstream成为你的类的成员:这将流的生命周期绑定到你的对象。std::istream使用该接口进行解析也可能比使用有些笨拙的接口更容易std::streambuf

如果你真的只想使用一个流缓冲区,你可以直接分配一个std::filebufusingnew filebufopen()文件流。要保留指向它的指针,您可能会使用std::unique_ptr<std::filebuf>(或者std::auto_ptr<std::filebuf>如果您不使用 C++ 2011)。使用指针类安排对象的自动释放。当然,指针仍然是你的类的成员,以确保生命周期正确。

您复制流缓冲区的尝试无效,因为流缓冲区不可复制。您需要直接创建文件缓冲区:

MyParser::MyParser(std::string const& filename)
    : pbuf(new std::filebuf)
{
    this-pbuf->open("whatever", std::ios_base::in);
    ...
}
于 2012-10-27T18:43:17.423 回答
0

你需要一些新的 C++ 教材,因为(对不起)但这是错误的。您需要将文件流声明为成员,new该程序中不需要任何地方,而且几乎没有人需要处理streambuf.

class MyParser {
    std::ifstream file;
public:
    MyParser(string filepath) {
        file.open(filepath, std::ios::in | std::ios::binary );
        char byte;
        file.read(sizeof(byte), &byte);
        printf("First Byte (in constructor): 0x%02X\n", byte);        
    }
    void readHeader() {
        char byte;
        file.read(sizeof(byte), &byte);
        printf("First Byte (in readHeader): 0x%02X\n", byte);   
    }
};
于 2012-10-27T18:53:54.827 回答