c++ - 在 C++ 中从二进制文件读取时将 char * 转换为 double?

标签 c++ qt

我正在编写二进制 I/O 以在我的应用程序中存储数据。

为了说明,假设我想将一个大小为 10 的 double 组存储到文件中

现在由于不能保证 double 在所有平台上都使用 8 个字节,所以文件的读取器需要稍微修改一下。 尽管我使用的是 Qt,但我认为问题主要出在将 char * 中读取的数据转换为 double 的方式上。读取的数据几乎为零。

例如1读作2.08607954259741e-317。

为什么每个 double 都被读取为零,即使它不是?

void FileString::SaveBinary()
{
    QFile *file = new QFile(fileName);
    if (!file->open(QFile::WriteOnly))
    {
        QString err = file->errorString();
        QString *msgText = new QString("Could not open the file from disk!\n");
        msgText->append(err);
        QString *msgTitle = new QString("ERROR: Could not open the file!");
        emit errMsg(msgTitle, msgText, "WARNING");
        delete file;
        return;
    }
    QDataStream out(file);
    QString line = "MyApp";
    out << line;
    line.setNum(size);//size = 10
    out << line;
    line.setNum(sizeof(double));
    out << line;

    for(int i = 0; i < size; i++)
    {
        out << array[i];
    }

    if(out.status() != QDataStream::Ok)
    {
        qCritical("error: " + QString::number(out.status()).toAscii());
    }
    file->close();
    delete file;
}

void FileString::ReadBinary()
{
    bool ok = false;
    QString line = "";
    QFile *file = new QFile(fileName);
    if (!file->open(QFile::ReadOnly))
    {
        QString err = file->errorString();
        QString *msgText = new QString("Could not open the file from disk!\n");
        msgText->append(err);
        QString *msgTitle = new QString("ERROR: Could not open the file!");
        emit errMsg(msgTitle, msgText, "WARNING");
        delete file;
        return;
    }

    QDataStream in(file);
    in >> line;
    if(line.simplified().contains("MyApp"))
    {
        in >> line;
        size = line.simplified().toInt();
        if(size == 10)
        {
            int mysize = 0;
            in >> line;
            mysize = line.simplified().toInt();
            if(1)//this block runs perfect
            {
                for(int i = 0; i < size; i++)
                {
                    in >> array[i];
                }

                if(in.status() == QDataStream::Ok)
                    ok = true;
                }
            }
            else if(1)//this block reads only zeros
            {
                char *reader = new char[mysize + 1];
                int read = 0;
                double *dptr = NULL;
                for(int i = 0; i < size; i++)
                {
                    read = in.readRawData(reader, mysize);
                    if(read != mysize)
                    {
                        break;
                    }

                    dptr = reinterpret_cast<double *>(reader);//garbage data stored in dptr, why?
                    if(dptr)
                    {
                        array[i] = *dptr;
                        dptr = NULL;
                    }
                    else
                    {
                        break;
                    }
                }


                if(in.status() == QDataStream::Ok)
                    ok = true;
                delete[] reader;
            }
        }
    }

    if(!ok || (in.status() != QDataStream::Ok))
    {
        qCritical("error : true" + " status = " + QString::number((int) in.status()).toAscii());
    }
    file->close();
    delete file;
}

编辑:

生成文件的内容

   & M y A p p   1 . 1 8 . 3 . 0    1 0    8?ð      @       @      @      @      @      @      @       @"      @$      

应该包含:

MyApp 1.18.3.010812345678910

"MyApp 1.18.3.0" "10" "8" "12345678910"

最佳答案

如果读取平台上的 sizeof double 与写入平台上的 sizeof double 不同,您希望读取什么?

假设您的写入平台上的 sizeof double 为 10。然后您将一个 10 字节的序列存储在一个表示 10 字节 double 的文件中。然后,如果您的读取平台上的 sizeof double 为 8,您将尝试将 10 字节 double 的位解析为 8 字节,这显然会以垃圾结束。

这是一个更直观的整数示例: 如果你有一个 2 字节的整数,比如 5。如果你将它存储在二进制文件中,你将得到一个 2 字节的序列:00000000 00000101。然后,如果您尝试读取与 1 字节 int 相同的数字,您将设法只读取第一个字节,即 00000000,结果仅为零。

考虑使用字符串来保存 double 以实现可移植性https://stackoverflow.com/a/6790009/817441

关于c++ - 在 C++ 中从二进制文件读取时将 char * 转换为 double?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21060910/

相关文章:

c++ - 为什么python 3.2的Python.h必须和Qt4一起先包含进来

c++ - (??) 的 QRegexp

c++ - 如何在 MS 编译器中用数组初始化 C++ vector/集合?

c++ - 是否为get_time定义了重复赋值?

python - 是否可以更改 QTableWidget 行标签的颜色?

python - 使用 Qt 排队(属性)动画

c++ - 线程 : doing processing in background of C++ Cinder app to keep the UI responsive

c++ - msbuild 链接步骤不运行

c++ - 来自 QDateTime 的 QT 的 fromTime_t 不起作用

c++ - Qt Android 上缺少 QSGContext