【问题标题】:Cannot get integer from stringstream in C++无法从 C++ 中的字符串流中获取整数
【发布时间】:2013-03-28 14:39:55
【问题描述】:

我只是搜索流(内存流或文件流)然后我找到了 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

编辑

我更改了代码,感谢 john,它适用于 fstream,但它仍然不适用于 stringstream

【问题讨论】:

    标签: c++


    【解决方案1】:

    您使用了错误类型的 I/O。当您说您应该使用二进制 I/O 时,您正在执行文本 I/O。

    例如不是

    int ojmver = 0; 
    stream >> ojmver;
    

    但是

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

    当然,由于大小问题(您确定 int 是四个字节吗?)和字节序,这可能仍然不正确。

    【讨论】:

    • 你可能也想要一个reinterpret_cast&lt;char*&gt;
    • 它给我错误'错误:“int*”类型的参数与“char”类型的参数不兼容'
    • @ChronoCross 仔细看,我想你错过了*
    • @john 哇,谢谢,现在它可以工作了,但它不能在 stringstream 上工作,这里的输出:长度:4231047 成功加载数据使用 fs 读取数据:格式:M30 OJM 版本:196608 Enc Sign1: 16 Enc Sign1: 0 Sample Count: 300 Read Data Using stringstream: 格式: M30 OJM Ver: 0 Enc Sign1: 0 Enc Sign1: 0 Sample Count: 0 按任意键继续。 . .
    • 问题是当您将数据写入字符串流stream &lt;&lt; buffer; 时,它将在第一个空字节处停止写入。您需要使用二进制(再次因为您正在编写二进制数据)。所以stream.write(buffer, length);。当然,您需要将长度传递给您的 getinfo 函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多