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 中创建了类似的应用程序,我测试了文件,它给了我正确的输出(在 C# 中使用 FileStream 和 MemoryStream 和 .NET Framework 2.0),这里是输出:

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

编辑

我更改了代码,感谢 john,它适用于 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 是四个字节吗?)和字节顺序,这可能仍然不正确。

于 2013-03-28T14:46:08.603 回答