Problem
Two files containing large number, one in each. You have only fopen(), int read(fp), fclose(), fwrite().
Add these two numbers and write in third file with the help of given functions only.
Solution
/*
============================================================================
Author : James Chen
Email : a.james.chen@gmail.com
Description : Add these two numbers and write in third file with the help of given functions only.
Created Date : 24-06-2013
Last Modified :
============================================================================
*/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <limits>
#include <string>
#include <vector>
using namespace std;
bool GenerateLargeNumFile(string& fileName, int len, bool random)
{
ofstream ofs(fileName);
if(!ofs.bad()){
for(int i = 0; i < len; ++i){
unsigned char num;
if(!random){
num = numeric_limits<unsigned char>::max() - i;
}
else{
num = rand();
}
ofs.write(reinterpret_cast<char *>(&num), sizeof(num) / sizeof(char));
}
}
else{
cout << "cannot open file for writing" << endl;
return false;
}
ofs.close();
return true;
}
bool GenerateLargeNumFile(string& fileName, unsigned char* arr, int len)
{
ofstream ofs(fileName);
if(!ofs.bad()){
for(int i = 0; i < len; ++i){
unsigned char num = arr[i];
ofs.write(reinterpret_cast<char *>(&num), sizeof(num) / sizeof(char));
}
}
else{
cout << "cannot open file for writing" << endl;
return false;
}
ofs.close();
return true;
}
bool PrintLargeNumFile(string& fileName, int leadingSpace = 0)
{
vector<char> v;
ifstream ifs(fileName);
if(!ifs.bad()){
unsigned char num;
while(true){
ifs.read(reinterpret_cast<char *>(&num), sizeof(num) / sizeof(char));
if(ifs.eof()) break;
v.push_back(num);
}
}
else{
cout << "cannot open " << fileName << endl;
return false;
}
ifs.close();
for(int i = 0; i < leadingSpace; ++ i){
cout << " ";
}
for(int i = v.size()- 1; i >= 0; --i){
unsigned char num = v[i];
cout.fill('0');
cout << " " << right << setw(2) << hex << (int)num;
}
cout << endl;
return true;
}
bool ReadLargeNumIntoVec(string& fileName, vector<unsigned char>& vec)
{
ifstream ifs(fileName);
if(!ifs.bad()){
unsigned char num;
while(true){
ifs.read(reinterpret_cast<char *>(&num), sizeof(num) / sizeof(char));
if(ifs.eof()) break;
vec.push_back(num);
}
}
else{
cout << "cannot open " << fileName << endl;
return false;
}
ifs.close();
return true;
}
bool WriteLargeNumIntoFile(string& fileName, vector<unsigned char>& vec)
{
ofstream ofs(fileName);
if(!ofs.bad()){
unsigned char num;
int i = 0;
while(i < vec.size()){
num = vec[i];
ofs.write(reinterpret_cast<char *>(&num), sizeof(num) / sizeof(char));
i++;
}
}
else{
cout << "cannot open " << fileName << endl;
return false;
}
ofs.close();
return true;
}
void AddTwoLargeNumb(string& outFileName, string& inFileName1, string& inFileName2)
{
vector<unsigned char> v1;
vector<unsigned char> v2;
vector<unsigned char> v3;
ReadLargeNumIntoVec(inFileName1, v1);
ReadLargeNumIntoVec(inFileName2, v2);
int minLen = v1.size() < v2.size() ? v1.size() : v2.size();
if(v1.size() > v2.size()){
v1.swap(v2);
}
int i = 0;
unsigned char carry(0);
unsigned char result;
unsigned char num1;
unsigned char num2;
int sum;
while(i < v1.size()){
num1 = v1[i];
num2 = v2[i];
sum = num1 + num2;
sum += carry;
result = sum & 0xFF;
carry = sum >> (sizeof(unsigned char) * 8);
v3.push_back(result);
i++;
}
while(i < v2.size()){
num2 = v2[i];
sum = carry + num2;
result = sum & numeric_limits<unsigned char>::max();
carry = sum >> (sizeof(unsigned char) * 8);
v3.push_back(result);
i++;
}
if(carry != 0){
v3.push_back(carry);
}
WriteLargeNumIntoFile(outFileName, v3);
}
int main(int argc, char* argv[])
{
string input1 = "input1";
string input2 = "input2";
string output = "output";
cout << "case 0 " << endl;
GenerateLargeNumFile(input1, 20, false);
GenerateLargeNumFile(input2, 10, false);
PrintLargeNumFile(input1, 1);
PrintLargeNumFile(input2, 11);
AddTwoLargeNumb(output, input1, input2);
PrintLargeNumFile(output, 1);
cout << "case 1" << endl;
unsigned char arr1[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
unsigned char arr2[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
GenerateLargeNumFile(input1, arr1, sizeof(arr1)/sizeof(unsigned char));
GenerateLargeNumFile(input2, arr1, sizeof(arr2)/sizeof(unsigned char));
PrintLargeNumFile(input1, 1);
PrintLargeNumFile(input2, 1);
AddTwoLargeNumb(output, input1, input2);
PrintLargeNumFile(output);
cout << "case 2" << endl;
GenerateLargeNumFile(input1, 20, true);
GenerateLargeNumFile(input2, 10, true);
PrintLargeNumFile(input1, 1);
PrintLargeNumFile(input2, 11);
AddTwoLargeNumb(output, input1, input2);
PrintLargeNumFile(output, 1);
cout << "case 3" << endl;
GenerateLargeNumFile(input1, 10, false);
GenerateLargeNumFile(input2, 20, true);
PrintLargeNumFile(input1, 11);
PrintLargeNumFile(input2, 1);
AddTwoLargeNumb(output, input1, input2);
PrintLargeNumFile(output, 1);
cout << "case 4" << endl;
GenerateLargeNumFile(input1, 10, true);
GenerateLargeNumFile(input2, 20, false);
PrintLargeNumFile(input1, 11);
PrintLargeNumFile(input2, 1);
AddTwoLargeNumb(output, input1, input2);
PrintLargeNumFile(output, 1);
return 0;
}
Output
case 0
ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff
f6 f7 f8 f9 fa fb fc fd fe ff
ec ed ee ef f0 f1 f2 f3 f4 f6 ed ef f1 f3 f5 f7 f9 fb fd fe
case 1
ff ff ff ff ff ff
ff ff ff ff ff ff
01 ff ff ff ff ff fe
case 2
3c db a6 b3 eb e9 bb f1 f1 49 90 52 ae d6 6c e1 84 be 23 29
b7 06 1c 0d 5e 24 99 3e 0c 87
3c db a6 b3 eb e9 bb f1 f1 4a 47 58 ca e3 cb 06 1d fc 2f b0
case 3
f6 f7 f8 f9 fa fb fc fd fe ff
d4 5d 1f 25 38 09 7d 5a 03 1f a6 8b bb 43 c8 4d 12 b3 de 47
d4 5d 1f 25 38 09 7d 5a 03 20 9d 83 b4 3d c3 49 0f b1 dd 46
case 4
0a 89 0d 13 3b 45 f5 96 fc cb
ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff
ec ed ee ef f0 f1 f2 f3 f4 f6 01 81 06 0d 36 41 f2 94 fb ca
Press any key to continue . . .