在 C++ 中使用 atof 将带小数的字符串转换为双精度
Converting string with decimal to double using atof in C++
在我的程序中,我正在尝试读取一个包含“$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
浮点数(float
、double
和 long double
)不适合存储精确值。它们很棒,因为它们可以很容易地对范围广泛的值进行许多不同的数学运算,但是有许多值无法使用 IEEE 浮点数精确表示。像 0.1
这样简单的值不能用类型准确表达,但输入和输出例程经常四舍五入,使它们看起来像是被正确处理了。
为了存储十进制完美值,我建议在读入时将值的两部分作为单独的整数处理,根据读入的小数位后的位数转换小数点,然后做一点点数学将两个部分转换为一个整数。对于美国货币,此整数的 LSB(最低有效位)可能代表 1 美分(除非小数美分需要准确表示)。可以使用类似的方法来输出值。
看起来这是由于浮点值的 cout 流的默认精度:http://www.cplusplus.com/reference/ios/ios_base/precision/
您必须告诉输出流您想要在点后固定精度为 2 位:
#include <iomanip>
// ...
std::cout << std::fixed << std::setprecision(2) << MONEYS << '\n';
在我的程序中,我正在尝试读取一个包含“$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
浮点数(float
、double
和 long double
)不适合存储精确值。它们很棒,因为它们可以很容易地对范围广泛的值进行许多不同的数学运算,但是有许多值无法使用 IEEE 浮点数精确表示。像 0.1
这样简单的值不能用类型准确表达,但输入和输出例程经常四舍五入,使它们看起来像是被正确处理了。
为了存储十进制完美值,我建议在读入时将值的两部分作为单独的整数处理,根据读入的小数位后的位数转换小数点,然后做一点点数学将两个部分转换为一个整数。对于美国货币,此整数的 LSB(最低有效位)可能代表 1 美分(除非小数美分需要准确表示)。可以使用类似的方法来输出值。
看起来这是由于浮点值的 cout 流的默认精度:http://www.cplusplus.com/reference/ios/ios_base/precision/
您必须告诉输出流您想要在点后固定精度为 2 位:
#include <iomanip>
// ...
std::cout << std::fixed << std::setprecision(2) << MONEYS << '\n';