【问题标题】:Converting string with decimal to double using atof in C++在 C++ 中使用 atof 将带小数的字符串转换为双精度
【发布时间】:2015-03-27 18:58:27
【问题描述】:

在我的程序中,我试图用“$876,725.38”这样的钱读取文件,我能够删除逗号和美元符号,现在我正在尝试使用 atof 将字符串转换为双精度,但我现在遇到了问题在转换之后打印MONEYS 之后,我得到了大部分时间之前的所有内容,但是一些在句点之前少于 6 位的部分在句点之后打印了一位或两位数。如果有人对此有解决方案,将不胜感激。我是 C++ 新手,需要帮助。谢谢!

主要问题:从字符串转换为双精度,小数点后的数据不打印。

    void readFile()
{
    string line, nuMoney, munney, cents;
    unsigned long dollarSign, period;


    ifstream myfile("MONEY.txt");

    int numLines = countLines("MONEY.txt");
    //cout << "NUMLINES: " << numLines << endl;

    if (!myfile.is_open())
    {
        cout << "ERROR: File could not be opened." << endl;
    }

    for (int i=0; i < numLines-1; i++)
    {
        getline(myfile, line, '\n');
        dollarSign = line.find('$');
        period = line.find('.');

        line.erase (remove(line.begin(), line.end(), ','), line.end()); //remove commas

        munney = line.substr(dollarSign+1);
        //cout << munney << endl;

        //cents = line.substr(period);
        //cout << "Cents: " << cents << endl;

        //double CENTUS = atof(cents.c_str());
        //cout << "CENTUS: " << CENTUS << endl;

        double MONEYS = atof(munney.c_str());
        cout << MONEYS << endl;

        list<double> acct;
        acct.push_back(MONEYS);

    }

}

样本输出:

937380
404261
814158
30218.1
69340.1
479891
517241
7203.55
975619
59219.4
900052
539774
336799
347700
532466
83496.8

【问题讨论】:

  • stackoverflow.com/help/mcve 请!!输入、预期输出和重现意外行为的完全可编译代码。
  • sooo... 有什么问题?我不明白,你的描述不清楚……
  • 将货币值存储为浮点数是一个非常糟糕的主意。有这个要求吗?
  • @JohnnyTran 一个整数。只需使用美分作为单位,而不是美元。
  • 您可以使用 int 乘以 100 来包含“美分”,除以 100 来获得货币价值。

标签: c++ string atof c-strings


【解决方案1】:

浮点数(floatdoublelong double)不适合存储精确值。它们很棒,因为它们可以轻松地对各种值进行大量不同的数学运算,但是有许多值无法使用 IEEE 浮点数精确表示。像0.1 这样简单的值不能完全由类型表示,但输入和输出例程通常会四舍五入以使其看起来处理正确。

为了存储十进制完美值,我建议在读取时将值的 2 部分视为单独的整数,根据读取的小数位后的位数转换小数点,然后做一些数学运算将两个部分转换为一个整数。对于美国货币,该整数的 LSB(最低有效位)可能代表 1 美分(除非需要准确表示小数美分)。可以使用类似的方法来输出这些值。

【讨论】:

  • 谢谢,我不太确定将 2 部分转换为单个 int 的数学位。请对此有更多的了解。
【解决方案2】:

您必须告诉输出流您想要点后 2 位的固定精度:

#include <iomanip>
// ...
std::cout << std::fixed << std::setprecision(2) << MONEYS << '\n';

【讨论】:

    【解决方案3】:

    看起来这是由于浮点值的 cout 流的默认精度:http://www.cplusplus.com/reference/ios/ios_base/precision/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-10
      • 2015-04-10
      • 1970-01-01
      • 2012-07-09
      • 2022-01-20
      • 1970-01-01
      相关资源
      最近更新 更多