1

私はc++で私の人生の新しい段階を始めようとしているacプログラマーです(私はまだ以下の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);
}

私のメインは単にパーサーを作成し、readHeaderを試みます

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

私の問題の解決策はストリームバッファを作成することだと思いますが、私にnewnew 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 に答える