如何在编写和读取文件时使用大数字?

时间:2011-03-05 16:51:12

标签: c++ iostream

我编写了一个代码,用于将数据从一个输入文件写入另一个输出文件,我用来读取输入文件的所有行

while (!inputfile.eof())

但在我的输出文件中,缺少最后一行。所以我想知道,如何防止这个错误?

我的第二个问题是:为了将数据写入文件,我使用了

Outputfile.write((char*)&a,sizeof(double));
Outputfile.write((char*)&b,sizeof(double));

这里a = 289814.150和b = 4320978.613但在输出文件中,它显示为

289814 4.32098e+006

a的值已四舍五入,b值显示为e值)那么这是什么原因以及如何解决此问题?

这里我尝试使用cout.setf(ios::fixed);,但如果这适用于屏幕上写的数据,我不知道如何修复此问题以在我的文件中写入双数据。

我想在输出文件中只写3位小数的实数值。请有人帮忙谢谢。

1 个答案:

答案 0 :(得分:2)

好的,基于评论,这里的意图(至少我希望)变得相当清楚:将文本格式的数字对转换为二进制格式,并且能够验证转换的数字是否准确地代表原始数据。 / p>

有很多方法可以做到这一点,但首先要记住的是,无论你做什么,将浮点数转换成文本(十进制)格式都可以并且通常会在某种程度上导致不准确。问题很简单:浮点(通常)以二进制形式完成。这意味着它只能表示分母为2的幂(或2的幂之和)的分数。显然,十进制使用十进制,因此分数可以由2的幂和5的幂组成。任何涉及2的幂(例如,0.2)的任何一个只能 以二进制近似 - 非常类似于尝试用十进制表示1/3 rd

这意味着您唯一合理的选择是允许小数和二进制版本之间存在某些差异。您可以期望的最好方法是将错误保持在最低限度。为了测试它,您可能需要/想要做的是将原始格式的二进制浮点数转换回十进制,并检查它是否关闭到原始格式(例如,忽略最终的错误)数字,至少+/- 1的错误。

转换本身应该是微不足道的:

#include <fstream>

int main(int argc, char **argv) {
    // checking argc omitted for clarity.
    std::ifstream infile(argv[1]);
    std::ofstream outfile(argv[2], std::ios::binary);

    double a, b;
    while (infile >> a && infile >> b) {
        outfile.write((char const *)&a, sizeof(a));
        outfile.write((char const *)&b, sizeof(b));
    }
    return 0;
}

验证数据并不是那么容易。一种可能性是这样的(从两个文件开始,一个二进制文件和一个文本):

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

int main(int argc, char **argv) { 

    std::string text;
    std::ostringstream converter;

    std::ifstream text_file(argv[1]);
    std::ifstream bin_file(argv[2], std::ios::binary);

    double bin_value;

    while (text_file >> text) {
        bin_file.read((char *)&bin_value, sizeof(bin_value));
        // the manipulators will probably need tweaking to match original format.
        converter << std::fixed << std::setw(3) << std::setprecision(3) << bin_value;
        if (converter.str() != text)
            ;// they're identical
        else if (converter.str().substr(0,3) == text.substr(0,3))
            ;// the first three digits are equal
        else
            ;// bigger error
    }
    return 0;
}

这更有可能需要一些调整来按照你想要的方式工作,但只要你确定原始数字的格式是一致的,那么一般的想法应该是大概的。