0

ストリーム (メモリ ストリームまたはファイル ストリーム) を検索したところ、fstream と stringstream が見つかりました

しかし、私は両方を試しましたが、整数を取得するときに常に間違った出力を与えます。これをテストするためにバイナリファイルを使用しています (データは文字列ではなく、データはバイトの束です)、ここに私のコードがあります:

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;
void getinfo(char* buffer, int length)
{
    stringstream stream(ios::in | ios::out | ios::binary);
    // write data to stream
    stream.write(buffer, length);

    // reset position
    stream.seekg(0);

    // get 4 bytes (value is OMC with null-byte at the end)
    char* format = new char[4];
    stream >> format;

    // get 4 byte (value is depending of file version)
    int ojmver = 0; 
    stream.read(reinterpret_cast<char*>(&ojmver), sizeof ojmver);

    // get 2 byte (encryption signature 1 that used for this file)
    short encsign1 = 0; 
    stream.read(reinterpret_cast<char*>(&encsign1), sizeof encsign1);

    // get 2 byte (encryption signature 2 that used for this file)
    short encsign2 = 0;
    stream.read(reinterpret_cast<char*>(&encsign2), sizeof encsign2);

    // get 4 byte (samples count)
    int samplecount = 0; 
    stream.read(reinterpret_cast<char*>(&samplecount), sizeof samplecount);

    // show info

    cout << "Format\t\t\t: " << format;
    cout << "\nOJM Ver\t\t\t: " << ojmver;
    cout << "\nEnc Sign1\t\t: " << encsign1;
    cout << "\nEnc Sign1\t\t: " << encsign2;
    cout << "\nSample Count\t\t: " << samplecount;
    cout << "\n\n";
}

int main()
{
    fstream fs = fstream("D:\\o2ma100.ojm", ios::in | ios::out | ios::binary);
    fs.seekg(0, fs.end);
    int length = fs.tellg();
    fs.seekg(0, fs.beg);

    char* buffer = new char[length];
    fs.read(buffer, length);

    if (fs)
        cout << "Length: " << length << "\nSuccess to load data\n";
    else
        cout << "Failed to load data\n";

    fs.seekg(0, fs.beg);

    // get 4 bytes (value is OMC with null-byte at the end)
    char* format = new char[4];
    fs.read(format, 4);

    // get 4 byte (value is depending of file version)
    int ojmver = 0; 
    fs.read(reinterpret_cast<char*>(&ojmver), sizeof ojmver);

    // get 2 byte (encryption signature 1 that used for this file)
    short encsign1 = 0; 
    fs.read(reinterpret_cast<char*>(&encsign1), sizeof encsign1);

    // get 2 byte (encryption signature 2 that used for this file)
    short encsign2 = 0;
    fs.read(reinterpret_cast<char*>(&encsign2), sizeof encsign2);

    // get 4 byte (samples count)
    int samplecount = 0; 
    fs.read(reinterpret_cast<char*>(&samplecount), sizeof samplecount);

    cout << "\nRead Data using fs:\n";

    cout << "Format\t\t\t: " << format;
    cout << "\nOJM Ver\t\t\t: " << ojmver;
    cout << "\nEnc Sign1\t\t: " << encsign1;
    cout << "\nEnc Sign1\t\t: " << encsign2;
    cout << "\nSample Count\t\t: " << samplecount;

    fs.close();

    cout << "\n\nRead Data Using stringstream:\n";
    getinfo(buffer, length);

    system("PAUSE");
    return 0;
}

次の結果が得られます。

Length: 4231047 // -> this correct :)
Success to load data // -> this correct :)

Read Data using fs:
Format                  : M30    // -> this correct :)
OJM Ver                 : 196608 // -> this correct :)
Enc Sign1               : 16     // -> this correct :)
Enc Sign1               : 0      // -> this correct :)
Sample Count            : 300    // -> perfect :D

Read Data Using stringstream:
Format                  : M30         // -> this correct :)
OJM Ver                 : 50331648    // -> this wrong :(
Enc Sign1               : 4096        // -> this wrong :(
Enc Sign1               : 0           // -> this wrong :(
Sample Count            : 76800       // -> this wrong :(

Press any key to continue . . .

私は C#.NET で同様のアプリケーションを作成していました。ファイルをテストしたところ、正しい出力が得られました (.NET Framework 2.0 で C# の FileStream と MemoryStream を使用)。

Length: 4231047 // -> Length is correct
Success to load data

Read Data using FileStream:
Format                  : M30     // -> this correct :)
OJM Ver                 : 196608  // -> this correct :)
Enc Sign1               : 16      // -> this correct :)
Enc Sign1               : 0       // -> this correct :)
Sample Count            : 300     // -> perfect :D

Read Data Using MemoryStream:
Format                  : M30     // -> this correct :)
OJM Ver                 : 196608  // -> this correct :)
Enc Sign1               : 16      // -> this correct :)
Enc Sign1               : 0       // -> this correct :)
Sample Count            : 300     // -> perfect :D

メモリとファイルを処理するストリームが必要なので、両方のストリームでデータを正しく読み取る方法が必要です...

誰でも私を助けることができますか?私はC++の初心者ですありがとう:D

編集

コードを変更しました。ジョンのおかげで、fstream では機能しましたが、stringstream ではまだ機能しません

4

1 に答える 1

0

間違った種類の I/O を使用しています。バイナリ I/O を使用する必要があると言ったときに、テキスト I/O を実行しています。

たとえば、そうではありません

int ojmver = 0; 
stream >> ojmver;

しかし

int ojmver = 0; 
stream.read(reinterpret_cast<char*>(&ojmver), sizeof ojmver);

もちろん、サイズの問題 (int が 4 バイトであることは確かですか?) とエンディアンのために、これはまだ正しくない可能性があります。

于 2013-03-28T14:46:08.603 に答える