В настоящее время я работаю над заданием, где мне приходится добавлять, вычитать и умножать числа до 20 цифр в длину. Я должен использовать класс и перегруженные операторы, и все входы/выходы должны записывать в файл вместе с экраном.
У меня все по большей части закончено. Написание всего файла - вот что заставило меня застрять. Я открываю файл для чтения входов в основной функции, я думал о передаче переменной потока в функции моего класса, но понял, что не будет работать, поскольку некоторые из них являются двоичными операторами и не будут принимать третьего аргумента.
Вот мой код: Заголовок файла:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class LargeIntegerNumber
{
public:
//Default constructor
LargeIntegerNumber();
//Set Array calls getNumber and convertNumber
void setArray(ostream& out);
//Obtains user input for string
void getNumber(ostream& out);
//Parses string into array
void convertNumber(LargeIntegerNumber array1);
//Compares the two numbers and displays result
void comparison(LargeIntegerNumber array1, LargeIntegerNumber array2, ostream& out);
friend void operator *(LargeIntegerNumber array1, LargeIntegerNumber array2);
friend void operator -(LargeIntegerNumber array1, LargeIntegerNumber array2);
friend void operator +(LargeIntegerNumber array1, LargeIntegerNumber array2);
friend istream& operator >>(istream& cin, LargeIntegerNumber& array1);
private:
int array[20];
string number;
int numSize;
int arrayNegative;
};
Мой файл реализации (из-за размера, я забыл некоторые вещи)
istream& operator >>(istream& cin, LargeIntegerNumber& array1)
{
//Prompt user to input string and retrieve result
cout<<"Please enter a number of up to 20 digits: "<<endl;
/*out<<"Please enter a number of up to 20 digits: "<<endl;*/
cin >> array1.number;
cout<<endl;
/*out << number;*/
/*out<<endl;*/
//Obtain the length of the number
array1.numSize = array1.number.length();
array1.convertNumber(array1);
return cin;
}
void LargeIntegerNumber::convertNumber(LargeIntegerNumber array1)
{
for (int i = 0; i < 20; i++)
array[i] = 0;
arrayNegative = 0;
for(int i =0; i < numSize; i++)
{
array[i] = number[numSize - i - 1] - 48; // Converting a character into an integer will give the ASCII code of the number, so to extract the actual numbe you have do - 48
//-3 is ascii code for negative symbol, if detected in string, number is negative
if (array[i] == -3)
{
//Set array is negative flag, then make '-' in string a 0
arrayNegative = 1;
array[i] = 0;
}
}
//Detects if string size is too large, takes - symbol into consideration
if ((numSize == 22) && (arrayNegative == 1))
{
cout<<"Number is greater than 20 digits, please try again."<<endl;
/*out<<"Number is greater than 20 digits, please try again."<<endl;*/
exit(1);
}
void operator *(LargeIntegerNumber array1, LargeIntegerNumber array2)
{
LargeIntegerNumber array3;
cout<<"Beginning Multiplication Process"<<endl;
// Multiplication
cout<<array1.number<<" * "<<array2.number<< " = ";
if ((array1.arrayNegative == 1) && (array2.arrayNegative == 0) || (array1.arrayNegative == 0) && (array2.arrayNegative == 1))
{
//If either number is negative, the result will be negative
cout<<"-";
}
for(int i =0; i< array2.numSize; i++)
{
for(int j = 0 ; j<array1.numSize; j++)
{
int tempNo = array1.array[j] * array2.array [i]; // Multiply each two digits
if ((i == 19) && (tempNo > 9))
{
cout<<endl;
cout<<"WARNING! THE RESULTS WILL BE GREATER THAN 20 DIGITS! ANSWER WILL BE INCORRECT!"<<endl;
}
int a = tempNo % 10; // Find out the result, and remove the carry part
array3.array[i+j] += a; // Save the result of the multiplication
a = array3.array[i+j]% 10; // Find out the result
int c = array3.array[i+j]/ 10; // Find if I have a carry after we add the numbers
array3.array[i+j] = a;
int b = tempNo / 10; // find out the carry
array3.array[i+j+1] += b+c; // Add the carry to the next number
if ((i+j == 19) && (b+c > 9))
{
cout<<endl;
cout<<"WARNING! THE RESULTS WILL BE GREATER THAN 20 DIGITS! ANSWER WILL BE INCORRECT!"<<endl;
}
}
}
//Display results
int i =19;
while ( array3.array[i] ==0)
i--;
// print out the result without 0s
do{
cout<<array3.array[i];
i--;
}while(i >=0);
cout<<endl;
}
}
И мой главный:
int main()
{
//Declaration of numbers
LargeIntegerNumber num1, num2;
int hold;
ofstream out;
string fileName;
//Open outfile
out.open("outfile.txt");
//if file not found
if (out.fail())
{
cout<<"File not found"<<endl;
exit(1);
}
//Menu
int menu;
char loop = 'Y';
do
{
cout<<"Please choose from the menu options below (Enter the cooresponding number on the left):"<<endl;
cout<<"1: Add two numbers"<<endl;
cout<<"2: Subtract two numbers"<<endl;
cout<<"3: Multiply two numbers"<<endl;
out<<"Please choose from the menu options below (Enter the cooresponding number on the left):"<<endl;
out<<"1: Add two numbers"<<endl;
out<<"2: Subtract two numbers"<<endl;
out<<"3: Multiply two numbers"<<endl;
cin>>menu;
cout<<endl;
out<<endl;
out<<menu;
out<<endl;
switch(menu)
{
//Addition
case 1:
cout<<"You have selected (1) Addition"<<endl;
out<<"You have selected (1) Addition"<<endl;
//Obtain both numbers, do arithmetic, display, then compare
cin >> num1;
cin >> num2;
/*num1.setArray(out);
num2.setArray(out);*/
num1 + num2;
num1.comparison(num1, num2, out);
break;
//Subtraction
case 2:
cout<<"You have selected (2) Subtraction"<<endl;
out<<"You have selected (2) Subtraction"<<endl;
cin >> num1;
cin >> num2;
/*num1.setArray(out);
num2.setArray(out);*/
num1 - num2;
num1.comparison(num1, num2, out);
break;
//Multiplication
case 3:
cout<<"You have selected (3) Multiplication"<<endl;
out<<"You have selected (3) Multiplication"<<endl;
cin >> num1;
cin >> num2;
/*num1.setArray(out);
num2.setArray(out);*/
num1 * num2;
num1.comparison(num1, num2, out);
break;
default:
cout<<"Not a valid menu option, please try again"<<endl;
out<<"Not a valid menu option, please try again"<<endl;
}
cout<<"Would you like to continue? (Enter Y/y for yes)"<<endl;
out<<"Would you like to continue? (Enter Y/y for yes)"<<endl;
cin>>loop;
out<<loop;
cout<<endl;
out<<endl;
}while ((loop == 'Y') || (loop == 'y'));
//Close file
out.close();
}
Большинство из них - это просто показать вам, с чем я работаю. Весь мой код работает отлично по большей части, я просто не уверен, как я могу переместить мою переменную потока из основного в мои двоичные операторы, так как я не могу их передать.
Одна из моих идей заключалась в том, чтобы заставить все арифметические операторы не иметь операторов cout (я все еще новичок в классах и операторах перегрузки, обычно не рекомендуется включать инструкции cin/out в перегруженные бинарные операторы?) И делать все инструкции cout в которая может принимать переменную ostream в качестве аргумента.
РЕДАКТИРОВАТЬ:
Приносим извинения, я должен был быть более ясным.
Моя программа должна написать все, что пользователь видит на экране (от ввода до вывода) в файл, а не только результаты.
Используйте общий метод вывода или записи в своем классе:
class LargeNumber
{
public:
std::ostream& write(std::ostream& out) const;
// Or you could overload the insertion operator
friend std::ostream& operator<<(std::ostream& out, const LargeNumber& ln);
}
std::ostream& operator<<(std::ostream& out,
const LargeNumber& ln)
{
out << ln.data_member;
return out;
}
Поскольку std::ofstream
наследуется от std::ostream
вы можете передать поток файла любому методу.
int main(void)
{
LargeNumber l;
ofstream out("output.txt");
// strategy 1:
l.write(out); // Output to file.
l.write(cout); // output to screen.
// strategy 2:
out << l; // Output to the file.
cout << l; // Output to the screen.
return 0;
}
array[i] = number[numSize - i - 1] - 48
почему бы вам не использовать'0'
вместо48
? Они эквивалентны, но использование'0'
сделает это утверждение намного более понятным.write
который используетstd::ostream
и передать std :: cout для записи на экран, а файловый поток - для записи в ваш файл.