重载运算符问题与加法
overloading operators issue with addition
添加 objects 时遇到问题。添加两个时似乎有效,例如:2.34 + 34.57 = 36.81,但添加 3 个或更多时失败,例如:6.78 + 9.81 + 4.59 = 79.59 <- 由于某种原因,总数似乎急剧增加。
可以忽略转换器函数,因为它们只是将数字总数转换为英文格式并且可以正常工作。中位数和排序以及 > 函数也能正常工作,因此问题可能出在 ostream、istream 或 + 函数中的某个地方。我在很多地方都使用了 cout,大多数异常数字似乎都出现在 + 函数中。
提前致谢。
Header:
#ifndef LAB2_H
#define LAB2_H
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class DollarAmount
{
double dollar = 0.00;
double cents = 0.00;
double avg = 0.00;
int maxsequence = 0;
string number;
public:
DollarAmount(double num1 = 0, double num2 = 0);
double getavg() const { return avg; };
double getDollar() const { return dollar; };
double getCent() const { return cents; };
int getmaxsequence() const { return maxsequence; };
friend istream& operator >> (istream& ins, DollarAmount& arg);
friend ostream& operator << (ostream& out, const DollarAmount& arg);
friend DollarAmount operator + (const DollarAmount& arg1, const DollarAmount& arg2);
friend bool operator > (const DollarAmount& arg1, const DollarAmount& arg2);
void sortobjects(DollarAmount a[], int length);
void median(DollarAmount a[], int length);
//All of the below functions are from lab 1
void converter1(string array1[], string array2[], string array3[], double m);
void converter2(double n);
函数:
#include <iostream>
#include <string>
#include <cstdlib>
#include "lab2.h"
using namespace std;
DollarAmount::DollarAmount(double num1, double num2)
{
dollar = num1;
cents = num2;
}
istream& operator >> (istream& ins, DollarAmount& arg)
{
double num1 = 0.00;
double num2 = 0.00;
//int num1 = 0;
//int num2 = 0;
char ch;
string s;
double num3;
bool wrongInput = false;
//ins >> num1 >> ch >> num2;
ins >> num3;
s = to_string(num3);
arg.number = s;
int index = s.find(".");
num1 = atof(s.substr(0, index).c_str());
num2 = atof(s.substr(index, 3).c_str());
do
{
if (wrongInput == true)
{
cout << "Enter the expenditure record (e.g., .95, coffee, enter -1 to end):$";
ins >> num1 >> ch >> num2;
}
else if (cin.fail() || num1 < 0 || num1 > 9999 || num2 > 99) //in case the above fails, e.g., ten dollor five cents...
{
cout << "Wrong input types. Try again:\n";
cin.clear(); //clear the error flags in cin
cin.ignore(2048, '\n'); //ignore everthing in the input buffer, up to 2048 char,
//up to the newline char =< ignore the rest of the line
wrongInput = true;
}
else
wrongInput = false;
} while (wrongInput == true || num1 < 0 || num1 > 9999 || num2 > 99); // if input false ask for input again
arg.dollar = num1;
arg.cents = num2;
arg.maxsequence = arg.getmaxsequence() + 1;
return ins;
}
ostream& operator << (ostream& out, const DollarAmount& arg)
{
out << arg.getDollar() + arg.getCent();
return out;
}
DollarAmount operator + (const DollarAmount& arg1, const DollarAmount& arg2)
{
DollarAmount temp;
double sum = 0.00;
double x = 0.00;
double y = 0.00;
string z;
temp.dollar = 0.00;
temp.cents = 0.00;
x = arg1.dollar + arg1.cents;
y = arg2.dollar + arg2.cents;
sum = x + y;
cout << "This is the sum: " << sum << endl;
z = to_string(sum);
int index = z.find(".");
temp.dollar = atof(z.substr(0, index).c_str());
temp.cents = atof(z.substr(index + 1, 2).c_str());
cout << "This is the dollar: " << temp.getDollar() << endl;
cout << "This is the cents: " << temp.getCent() << endl;
return temp;
}
bool operator > (const DollarAmount& arg1, const DollarAmount& arg2)
{
DollarAmount temp;
double x, y;
x = arg1.dollar + arg1.cents;
y = arg2.dollar + arg2.cents;
if (x > y)
return true;
else
return false;
}
void DollarAmount::sortobjects(DollarAmount a[], int length)
{
int i;
int last = length - 1; //point to the index of last element in unsorted part of the array
for (int pass = 0; pass < length; pass++)
{
//a[0]...a[last] is not sorted
//repeated bubble the largest element in this range to the end ...
for (i = 0; i <= last - 1; i++)
{
if (a[i] > a[i + 1])
{
//swap
DollarAmount tmp;
tmp = a[i + 1];
a[i + 1] = a[i];
a[i] = tmp;
}
}
//at this point, the largest element in a[0...last] is stored in a[last]
//unsorted part is now a[0...last-1]
last = last - 1;
}
}
void DollarAmount::median(DollarAmount a[], int length)
{
DollarAmount temp;
int mid;
double average = 0.00;
double x = 0.00;
double y = 0.00;
if (length % 2 == 0)
{
mid = length / 2;
int test = mid - 1;
x = a[mid].dollar + a[mid].cents;
y = a[test].dollar + a[test].cents;
average = (x + y) / 2.00;
temp.avg = average;
cout << temp.getavg();
}
else
{
mid = length / 2;
x = a[mid].dollar + a[mid].cents;
average = x;
temp.avg = average;
cout << temp.getavg();
}
}
void DollarAmount::converter1(string array1[], string array2[], string array3[], double m)
{
string a;
string b;
string c;
string d;
int num1 = 0;
d = to_string(m);
int index = d.find(".");
int x = atoi(d.substr(0, index).c_str());
if (x < 100)
{
if (x > 0 && x < 10)
{
a = array1[x - 1];
cout << a;
}
else if (x == 10)
{
a = array2[0];
cout << a;
}
else if (x > 10 && x < 20)
{
a = array2[x - 10];
cout << a;
}
else if (x == 20)
{
a = array3[0];
cout << a;
}
else if (x > 20 && x < 30)
{
num1 = x - 20;
b = array3[0];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 30)
{
a = array3[1];
cout << a;
}
else if (x > 30 && x < 40)
{
num1 = x - 30;
b = array3[1];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 40)
{
a = array3[2];
cout << a;
}
else if (x > 40 && x < 50)
{
num1 = x - 40;
b = array3[2];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 50)
{
a = array3[3];
cout << a;
}
else if (x > 50 && x < 60)
{
num1 = x - 50;
b = array3[3];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 60)
{
a = array3[4];
cout << a;
}
else if (x > 60 && x < 70)
{
num1 = x - 60;
b = array3[4];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 70)
{
a = array3[5];
cout << a;
}
else if (x > 70 && x < 80)
{
num1 = x - 70;
b = array3[5];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 80)
{
a = array3[6];
cout << a;
}
else if (x > 80 && x < 90)
{
num1 = x - 80;
b = array3[6];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 90)
{
a = array3[7];
cout << a;
}
else
{
num1 = x - 90;
b = array3[7];
a = array1[num1 - 1];
cout << b << " " << a;
}
}
else if (x < 1000)
{
if (x == 100)
{
a = array1[0] + " hundred ";
cout << a;
}
else if (x == 200)
{
a = array1[1] + " hundred ";
cout << a;
}
else if (x == 300)
{
a = array1[2] + " hundred ";
cout << a;
}
else if (x == 400)
{
a = array1[3] + " hundred ";
cout << a;
}
else if (x == 500)
{
a = array1[4] + " hundred ";
cout << a;
}
else if (x == 600)
{
a = array1[5] + " hundred ";
cout << a;
}
else if (x == 700)
{
a = array1[6] + " hundred ";
cout << a;
}
else if (x == 800)
{
a = array1[7] + " hundred ";
cout << a;
}
else if (x == 900)
{
a = array1[8] + " hundred ";
cout << a;
}
else
{
// a + "hundred + b + c
num1 = x / 100;
a = array1[num1 - 1];
cout << a << " hundred ";
converter1(array1, array2, array3, (x % 100));
}
}
else
{
if (x == 1000)
{
a = array1[0] + " thousand";
cout << a;
}
else if (x == 2000)
{
a = array1[1] + " thousand";
cout << a;
}
else if (x == 3000)
{
a = array1[2] + " thousand";
cout << a;
}
else if (x == 4000)
{
a = array1[3] + " thousand";
cout << a;
}
else if (x == 5000)
{
a = array1[4] + " thousand";
cout << a;
}
else if (x == 6000)
{
a = array1[5] + " thousand";
cout << a;
}
else if (x == 7000)
{
a = array1[6] + " thousand";
cout << a;
}
else if (x == 8000)
{
a = array1[7] + " thousand";
cout << a;
}
else if (x == 9000)
{
a = array1[8] + " thousand";
cout << a;
}
else
{
//a + "thousand" + b + "hundred" + c + d
num1 = x / 1000;
a = array1[num1 - 1];
cout << a << " thousand ";
converter1(array1, array2, array3, (x % 1000));
}
}
}
void DollarAmount::converter2(double n)
{
cout << n << "/100)" << endl;
}
主要:
#include <iostream>
#include <string>
#include <cstdlib>
#include "lab2.h"
using namespace std;
const int INIT_SIZE = 10;
const int a = 9;
const int b = 10;
const int c = 8;
int main()
{
string one[a] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
string two[b] = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
string three[c] = { "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" };
DollarAmount* arr = new DollarAmount[INIT_SIZE];
DollarAmount* ptr = NULL;
int avg = 0;
int arr_size = INIT_SIZE;
int arr_len = 0; // actual number of objects stored in it , also the index
// of next free slot in arr
bool lastInput = false;
do
{
if (arr_len == arr_size)
{ // the array is full, need to grow!
//allocate an array double the cur_size
ptr = new DollarAmount[arr_size * 2];
//copy each element in arr into the new array that ptr points to...
// Todo: please figure out how to do this...(hint: use a for loop)
for (int i = 0; i < arr_size; i++)
{
ptr[i] = arr[i];
}
//now we delete the current arr
delete[] arr;
arr = ptr;
arr_size = arr_size * 2;
}
cout << "Enter the expenditure record (e.g., .95, coffee, enter 0.0 to end):$";
cin >> arr[arr_len]; //read in a dollar amount from cin we will allow input such as 0.0
//If the last read dollar amount is 0.0, then it's the end
if (arr[arr_len].getDollar() == 0 && arr[arr_len].getCent() == 0)
lastInput = true;
else //we only increment arr_len for input that's not 0.0
arr_len++;
} while (lastInput == false);
DollarAmount total, temp, loopingtotal;
total = arr[0] + arr[1];
//cout << "The first total: " << total << endl;
//cout << "This is sum of first two: " << total;
//A loopt to add all DollarAmount up, and display the total
for (int i = 2; i < arr_len; i++)
{
total = total + arr[i];
cout << "The total for this " << i << " time is: " << total << endl;
}
//cout << "This is the sum after loop " << total;
//Call Sort function to sort the array of DollarAmount
temp.sortobjects(arr, arr_len);
//Display the sorted array, and the median
cout << "Sorted list of expenditure:" << endl;
for (int i = 0; i < arr_len; i++)
{
cout << arr[i] << endl;
}
//cout << "This is the total cents: " << total.getCent();
//cout << "This is the total dollar: " << total.getDollar();
cout << "The total is $" << total.getDollar() << "." << total.getCent();
cout << " (";
temp.converter1(one, two, three, total.getDollar());
cout << " and ";
temp.converter2(total.getCent());
cout << "The median is ";
temp.median(arr, arr_len);
cout << "." << endl;
cout << "Bye!";
return 0;
}
TL;DR - 让你的 class 尽可能简单,以充分代表一件事。输入验证可能是一个兔子洞,所以只需担心您当前的要求即可。在 class 之外进行所有计算(因为它不相关)。
您比需要更加努力地工作。首先,你的 class 很乱。 class 应该有一个单一的目的,我很清楚你的没有。
从钱开始 class:
class Money {
public:
Money() = default;
Money(int d, int c)
: cents_m(d * 100 + c)
{
}
inline int dollars() const { return cents_m / 100; }
inline int cents() const { return cents_m % 100; }
friend std::istream& operator>>(std::istream& sin, Money& obj);
friend std::ostream& operator<<(std::ostream& sout, const Money& obj);
friend const Money operator+(const Money& lhs, const Money& rhs);
private:
int cents_m = 0;
};
排除所有多余的数学垃圾,它不属于 Money class。它属于您需要将这种工作作为函数完成的任何地方。请注意,您现在只存储美分,而不是分开的美元和美分。 5 美元是 500 便士,这使得所有简单的货币计算变得更容易 很多。如果您处理利率和股票交易,那么您会关心几分钱,但我猜您在这里不关心。
我正在利用一些 C++11 功能,例如默认成员初始化和 default
ing 默认构造函数,现在 cents_m
已为我默认初始化。我也在使用初始化部分,你也应该使用。
为了展示货币数学变得多么简单,这里是 operator+()
函数:
const Money operator+(const Money& lhs, const Money& rhs)
{
int sum = lhs.cents_m + rhs.cents_m;
return Money(sum / 100, sum % 100);
}
以下是其他运算符:
std::istream& operator>>(std::istream& sin, Money& obj)
{
std::string tmp;
std::getline(sin, tmp);
if (!(tmp.length() > 0)) {
obj = Money();
return sin;
}
if (tmp[0] == '$') {
tmp = tmp.substr(1);
}
std::size_t location;
double value = std::stod(tmp, &location);
if (location != tmp.length()) {
obj = Money();
} else {
int cents = std::lround(value * 100);
obj = Money(cents / 100, cents % 100);
}
return sin;
}
std::ostream& operator<<(std::ostream& sout, const Money& obj)
{
bool isNegative = obj.cents_m < 0;
std::string tmp;
int dollars = abs(obj.cents_m / 100);
int cents = abs(obj.cents_m % 100);
if (isNegative) {
tmp += "(";
}
tmp += ("$" + std::to_string(dollars) + ".");
if (cents < 10) {
tmp += ("0" + std::to_string(cents));
} else {
tmp += std::to_string(obj.cents_m % 100);
}
if (isNegative) {
tmp += ")";
}
return sout << tmp;
}
注意事项:输入流运算符重载可以解释输入的“$”(但仅作为第一个字符),但它可能无法解释负数钱(因为必须输入 $-3.50
,但没有人这样做)。输入验证并不简单,你走多远取决于你的老师的要求。我承认我的代码很容易在一些无效输入下崩溃,因为我不想变得非常全面(而且我们仍然只谈论 ASCII)。
我还选择简单地让 Money 对象在我检测到的几个无效输入上存储默认值。运算符重载中带有循环的错误消息是个坏主意(这不是这些运算符对其他任何事物的行为方式;重载应该按预期运行)。要么在后台处理错误,要么抛出异常。这是一个个案的决定,我认为在这种情况下可以默默地处理这个问题。
如果允许您假设始终输入有效数字,则运算符重载会变得非常简单。
流输出运算符重载至少可以打印负货币。
这里有一个简短的主要功能来测试金钱 class:
int main()
{
Money one(6, 78);
Money two(9, 81);
Money thr(4, 59);
std::cout << (one + two + thr) << '\n';
Money fou;
std::cout << "Give me some money: ";
std::cin >> fou;
std::cout << "You only gave me " << fou << "?\n";
}
一些一般性建议:在处理编程问题时,您应该做的第一件事是很少编写代码。思考它,想象它,用你自己的话写出需求,并思考你将如何解决它(不是用代码,而是你需要采取的实际步骤)。代码是工具,不是解决方案。
添加 objects 时遇到问题。添加两个时似乎有效,例如:2.34 + 34.57 = 36.81,但添加 3 个或更多时失败,例如:6.78 + 9.81 + 4.59 = 79.59 <- 由于某种原因,总数似乎急剧增加。
可以忽略转换器函数,因为它们只是将数字总数转换为英文格式并且可以正常工作。中位数和排序以及 > 函数也能正常工作,因此问题可能出在 ostream、istream 或 + 函数中的某个地方。我在很多地方都使用了 cout,大多数异常数字似乎都出现在 + 函数中。
提前致谢。
Header:
#ifndef LAB2_H
#define LAB2_H
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class DollarAmount
{
double dollar = 0.00;
double cents = 0.00;
double avg = 0.00;
int maxsequence = 0;
string number;
public:
DollarAmount(double num1 = 0, double num2 = 0);
double getavg() const { return avg; };
double getDollar() const { return dollar; };
double getCent() const { return cents; };
int getmaxsequence() const { return maxsequence; };
friend istream& operator >> (istream& ins, DollarAmount& arg);
friend ostream& operator << (ostream& out, const DollarAmount& arg);
friend DollarAmount operator + (const DollarAmount& arg1, const DollarAmount& arg2);
friend bool operator > (const DollarAmount& arg1, const DollarAmount& arg2);
void sortobjects(DollarAmount a[], int length);
void median(DollarAmount a[], int length);
//All of the below functions are from lab 1
void converter1(string array1[], string array2[], string array3[], double m);
void converter2(double n);
函数:
#include <iostream>
#include <string>
#include <cstdlib>
#include "lab2.h"
using namespace std;
DollarAmount::DollarAmount(double num1, double num2)
{
dollar = num1;
cents = num2;
}
istream& operator >> (istream& ins, DollarAmount& arg)
{
double num1 = 0.00;
double num2 = 0.00;
//int num1 = 0;
//int num2 = 0;
char ch;
string s;
double num3;
bool wrongInput = false;
//ins >> num1 >> ch >> num2;
ins >> num3;
s = to_string(num3);
arg.number = s;
int index = s.find(".");
num1 = atof(s.substr(0, index).c_str());
num2 = atof(s.substr(index, 3).c_str());
do
{
if (wrongInput == true)
{
cout << "Enter the expenditure record (e.g., .95, coffee, enter -1 to end):$";
ins >> num1 >> ch >> num2;
}
else if (cin.fail() || num1 < 0 || num1 > 9999 || num2 > 99) //in case the above fails, e.g., ten dollor five cents...
{
cout << "Wrong input types. Try again:\n";
cin.clear(); //clear the error flags in cin
cin.ignore(2048, '\n'); //ignore everthing in the input buffer, up to 2048 char,
//up to the newline char =< ignore the rest of the line
wrongInput = true;
}
else
wrongInput = false;
} while (wrongInput == true || num1 < 0 || num1 > 9999 || num2 > 99); // if input false ask for input again
arg.dollar = num1;
arg.cents = num2;
arg.maxsequence = arg.getmaxsequence() + 1;
return ins;
}
ostream& operator << (ostream& out, const DollarAmount& arg)
{
out << arg.getDollar() + arg.getCent();
return out;
}
DollarAmount operator + (const DollarAmount& arg1, const DollarAmount& arg2)
{
DollarAmount temp;
double sum = 0.00;
double x = 0.00;
double y = 0.00;
string z;
temp.dollar = 0.00;
temp.cents = 0.00;
x = arg1.dollar + arg1.cents;
y = arg2.dollar + arg2.cents;
sum = x + y;
cout << "This is the sum: " << sum << endl;
z = to_string(sum);
int index = z.find(".");
temp.dollar = atof(z.substr(0, index).c_str());
temp.cents = atof(z.substr(index + 1, 2).c_str());
cout << "This is the dollar: " << temp.getDollar() << endl;
cout << "This is the cents: " << temp.getCent() << endl;
return temp;
}
bool operator > (const DollarAmount& arg1, const DollarAmount& arg2)
{
DollarAmount temp;
double x, y;
x = arg1.dollar + arg1.cents;
y = arg2.dollar + arg2.cents;
if (x > y)
return true;
else
return false;
}
void DollarAmount::sortobjects(DollarAmount a[], int length)
{
int i;
int last = length - 1; //point to the index of last element in unsorted part of the array
for (int pass = 0; pass < length; pass++)
{
//a[0]...a[last] is not sorted
//repeated bubble the largest element in this range to the end ...
for (i = 0; i <= last - 1; i++)
{
if (a[i] > a[i + 1])
{
//swap
DollarAmount tmp;
tmp = a[i + 1];
a[i + 1] = a[i];
a[i] = tmp;
}
}
//at this point, the largest element in a[0...last] is stored in a[last]
//unsorted part is now a[0...last-1]
last = last - 1;
}
}
void DollarAmount::median(DollarAmount a[], int length)
{
DollarAmount temp;
int mid;
double average = 0.00;
double x = 0.00;
double y = 0.00;
if (length % 2 == 0)
{
mid = length / 2;
int test = mid - 1;
x = a[mid].dollar + a[mid].cents;
y = a[test].dollar + a[test].cents;
average = (x + y) / 2.00;
temp.avg = average;
cout << temp.getavg();
}
else
{
mid = length / 2;
x = a[mid].dollar + a[mid].cents;
average = x;
temp.avg = average;
cout << temp.getavg();
}
}
void DollarAmount::converter1(string array1[], string array2[], string array3[], double m)
{
string a;
string b;
string c;
string d;
int num1 = 0;
d = to_string(m);
int index = d.find(".");
int x = atoi(d.substr(0, index).c_str());
if (x < 100)
{
if (x > 0 && x < 10)
{
a = array1[x - 1];
cout << a;
}
else if (x == 10)
{
a = array2[0];
cout << a;
}
else if (x > 10 && x < 20)
{
a = array2[x - 10];
cout << a;
}
else if (x == 20)
{
a = array3[0];
cout << a;
}
else if (x > 20 && x < 30)
{
num1 = x - 20;
b = array3[0];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 30)
{
a = array3[1];
cout << a;
}
else if (x > 30 && x < 40)
{
num1 = x - 30;
b = array3[1];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 40)
{
a = array3[2];
cout << a;
}
else if (x > 40 && x < 50)
{
num1 = x - 40;
b = array3[2];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 50)
{
a = array3[3];
cout << a;
}
else if (x > 50 && x < 60)
{
num1 = x - 50;
b = array3[3];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 60)
{
a = array3[4];
cout << a;
}
else if (x > 60 && x < 70)
{
num1 = x - 60;
b = array3[4];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 70)
{
a = array3[5];
cout << a;
}
else if (x > 70 && x < 80)
{
num1 = x - 70;
b = array3[5];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 80)
{
a = array3[6];
cout << a;
}
else if (x > 80 && x < 90)
{
num1 = x - 80;
b = array3[6];
a = array1[num1 - 1];
cout << b << " " << a;
}
else if (x == 90)
{
a = array3[7];
cout << a;
}
else
{
num1 = x - 90;
b = array3[7];
a = array1[num1 - 1];
cout << b << " " << a;
}
}
else if (x < 1000)
{
if (x == 100)
{
a = array1[0] + " hundred ";
cout << a;
}
else if (x == 200)
{
a = array1[1] + " hundred ";
cout << a;
}
else if (x == 300)
{
a = array1[2] + " hundred ";
cout << a;
}
else if (x == 400)
{
a = array1[3] + " hundred ";
cout << a;
}
else if (x == 500)
{
a = array1[4] + " hundred ";
cout << a;
}
else if (x == 600)
{
a = array1[5] + " hundred ";
cout << a;
}
else if (x == 700)
{
a = array1[6] + " hundred ";
cout << a;
}
else if (x == 800)
{
a = array1[7] + " hundred ";
cout << a;
}
else if (x == 900)
{
a = array1[8] + " hundred ";
cout << a;
}
else
{
// a + "hundred + b + c
num1 = x / 100;
a = array1[num1 - 1];
cout << a << " hundred ";
converter1(array1, array2, array3, (x % 100));
}
}
else
{
if (x == 1000)
{
a = array1[0] + " thousand";
cout << a;
}
else if (x == 2000)
{
a = array1[1] + " thousand";
cout << a;
}
else if (x == 3000)
{
a = array1[2] + " thousand";
cout << a;
}
else if (x == 4000)
{
a = array1[3] + " thousand";
cout << a;
}
else if (x == 5000)
{
a = array1[4] + " thousand";
cout << a;
}
else if (x == 6000)
{
a = array1[5] + " thousand";
cout << a;
}
else if (x == 7000)
{
a = array1[6] + " thousand";
cout << a;
}
else if (x == 8000)
{
a = array1[7] + " thousand";
cout << a;
}
else if (x == 9000)
{
a = array1[8] + " thousand";
cout << a;
}
else
{
//a + "thousand" + b + "hundred" + c + d
num1 = x / 1000;
a = array1[num1 - 1];
cout << a << " thousand ";
converter1(array1, array2, array3, (x % 1000));
}
}
}
void DollarAmount::converter2(double n)
{
cout << n << "/100)" << endl;
}
主要:
#include <iostream>
#include <string>
#include <cstdlib>
#include "lab2.h"
using namespace std;
const int INIT_SIZE = 10;
const int a = 9;
const int b = 10;
const int c = 8;
int main()
{
string one[a] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
string two[b] = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
string three[c] = { "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" };
DollarAmount* arr = new DollarAmount[INIT_SIZE];
DollarAmount* ptr = NULL;
int avg = 0;
int arr_size = INIT_SIZE;
int arr_len = 0; // actual number of objects stored in it , also the index
// of next free slot in arr
bool lastInput = false;
do
{
if (arr_len == arr_size)
{ // the array is full, need to grow!
//allocate an array double the cur_size
ptr = new DollarAmount[arr_size * 2];
//copy each element in arr into the new array that ptr points to...
// Todo: please figure out how to do this...(hint: use a for loop)
for (int i = 0; i < arr_size; i++)
{
ptr[i] = arr[i];
}
//now we delete the current arr
delete[] arr;
arr = ptr;
arr_size = arr_size * 2;
}
cout << "Enter the expenditure record (e.g., .95, coffee, enter 0.0 to end):$";
cin >> arr[arr_len]; //read in a dollar amount from cin we will allow input such as 0.0
//If the last read dollar amount is 0.0, then it's the end
if (arr[arr_len].getDollar() == 0 && arr[arr_len].getCent() == 0)
lastInput = true;
else //we only increment arr_len for input that's not 0.0
arr_len++;
} while (lastInput == false);
DollarAmount total, temp, loopingtotal;
total = arr[0] + arr[1];
//cout << "The first total: " << total << endl;
//cout << "This is sum of first two: " << total;
//A loopt to add all DollarAmount up, and display the total
for (int i = 2; i < arr_len; i++)
{
total = total + arr[i];
cout << "The total for this " << i << " time is: " << total << endl;
}
//cout << "This is the sum after loop " << total;
//Call Sort function to sort the array of DollarAmount
temp.sortobjects(arr, arr_len);
//Display the sorted array, and the median
cout << "Sorted list of expenditure:" << endl;
for (int i = 0; i < arr_len; i++)
{
cout << arr[i] << endl;
}
//cout << "This is the total cents: " << total.getCent();
//cout << "This is the total dollar: " << total.getDollar();
cout << "The total is $" << total.getDollar() << "." << total.getCent();
cout << " (";
temp.converter1(one, two, three, total.getDollar());
cout << " and ";
temp.converter2(total.getCent());
cout << "The median is ";
temp.median(arr, arr_len);
cout << "." << endl;
cout << "Bye!";
return 0;
}
TL;DR - 让你的 class 尽可能简单,以充分代表一件事。输入验证可能是一个兔子洞,所以只需担心您当前的要求即可。在 class 之外进行所有计算(因为它不相关)。
您比需要更加努力地工作。首先,你的 class 很乱。 class 应该有一个单一的目的,我很清楚你的没有。
从钱开始 class:
class Money {
public:
Money() = default;
Money(int d, int c)
: cents_m(d * 100 + c)
{
}
inline int dollars() const { return cents_m / 100; }
inline int cents() const { return cents_m % 100; }
friend std::istream& operator>>(std::istream& sin, Money& obj);
friend std::ostream& operator<<(std::ostream& sout, const Money& obj);
friend const Money operator+(const Money& lhs, const Money& rhs);
private:
int cents_m = 0;
};
排除所有多余的数学垃圾,它不属于 Money class。它属于您需要将这种工作作为函数完成的任何地方。请注意,您现在只存储美分,而不是分开的美元和美分。 5 美元是 500 便士,这使得所有简单的货币计算变得更容易 很多。如果您处理利率和股票交易,那么您会关心几分钱,但我猜您在这里不关心。
我正在利用一些 C++11 功能,例如默认成员初始化和 default
ing 默认构造函数,现在 cents_m
已为我默认初始化。我也在使用初始化部分,你也应该使用。
为了展示货币数学变得多么简单,这里是 operator+()
函数:
const Money operator+(const Money& lhs, const Money& rhs)
{
int sum = lhs.cents_m + rhs.cents_m;
return Money(sum / 100, sum % 100);
}
以下是其他运算符:
std::istream& operator>>(std::istream& sin, Money& obj)
{
std::string tmp;
std::getline(sin, tmp);
if (!(tmp.length() > 0)) {
obj = Money();
return sin;
}
if (tmp[0] == '$') {
tmp = tmp.substr(1);
}
std::size_t location;
double value = std::stod(tmp, &location);
if (location != tmp.length()) {
obj = Money();
} else {
int cents = std::lround(value * 100);
obj = Money(cents / 100, cents % 100);
}
return sin;
}
std::ostream& operator<<(std::ostream& sout, const Money& obj)
{
bool isNegative = obj.cents_m < 0;
std::string tmp;
int dollars = abs(obj.cents_m / 100);
int cents = abs(obj.cents_m % 100);
if (isNegative) {
tmp += "(";
}
tmp += ("$" + std::to_string(dollars) + ".");
if (cents < 10) {
tmp += ("0" + std::to_string(cents));
} else {
tmp += std::to_string(obj.cents_m % 100);
}
if (isNegative) {
tmp += ")";
}
return sout << tmp;
}
注意事项:输入流运算符重载可以解释输入的“$”(但仅作为第一个字符),但它可能无法解释负数钱(因为必须输入 $-3.50
,但没有人这样做)。输入验证并不简单,你走多远取决于你的老师的要求。我承认我的代码很容易在一些无效输入下崩溃,因为我不想变得非常全面(而且我们仍然只谈论 ASCII)。
我还选择简单地让 Money 对象在我检测到的几个无效输入上存储默认值。运算符重载中带有循环的错误消息是个坏主意(这不是这些运算符对其他任何事物的行为方式;重载应该按预期运行)。要么在后台处理错误,要么抛出异常。这是一个个案的决定,我认为在这种情况下可以默默地处理这个问题。
如果允许您假设始终输入有效数字,则运算符重载会变得非常简单。
流输出运算符重载至少可以打印负货币。
这里有一个简短的主要功能来测试金钱 class:
int main()
{
Money one(6, 78);
Money two(9, 81);
Money thr(4, 59);
std::cout << (one + two + thr) << '\n';
Money fou;
std::cout << "Give me some money: ";
std::cin >> fou;
std::cout << "You only gave me " << fou << "?\n";
}
一些一般性建议:在处理编程问题时,您应该做的第一件事是很少编写代码。思考它,想象它,用你自己的话写出需求,并思考你将如何解决它(不是用代码,而是你需要采取的实际步骤)。代码是工具,不是解决方案。