Multiplication of Large Numbers using Linked Lists

/*
Input 2 numbers and get the product.
This version does not handle decimal or negative numbers or any wrong input.
Error handling is minimal.
*/

using namespace std;
#include <iostream>

const int PARTLENGTH = 8;

class Number
{
public:
	long part;
	Number * next;
	Number()
	{
		part = 0;
		next = NULL;
	}
};

//Function Declarations
string multiply(string, string);          // Multiply 2 numbers
int numparts(string);                     // Find out how many sections the string has
Number * makeEmptyLinkedList(int);        // Create a linked list with so many nodes
void fillLinkedList(Number *, string);    // Inserts the relevant values into the linked list
void movenext(Number * &);                // Updates the pointer to the next record

void mult(Number *, Number *, long);      // Multiply the linked list with a value and return it in another list
void adjust(Number *);                    // Adjust the arithmetic overflow of a number
void mult10(Number *);                    // Multiply 10 to the linked list
void add(Number *, Number *);             // Add 2 linked lists together

void appendNumberToBuffer(Number *, string &);  // Recurse through linked list and append to buffer
string removeLeadingZeros(string);              // Remove leading zeros from a string
long tenpower(int);                             // Function for getting 10 ^ value passed
//End function declarations

int main(int argc, char *argv[])
{
	//First 2 command-line arguments constitute the numbers
	string strFirst  = removeLeadingZeros(string(argv[1]));
	string strSecond = removeLeadingZeros(string(argv[2]));
	
	cout << "The product is " << multiply(strFirst, strSecond) << endl;
	return 0;
}

string multiply(string strFirst, string strSecond)
{
	int nodes_1 = numparts(strFirst);
	Number * nFirst = makeEmptyLinkedList(nodes_1);
	
	fillLinkedList(nFirst, strFirst);
	Number * nInter = makeEmptyLinkedList(nodes_1 + 1);
	Number * nTotal = makeEmptyLinkedList(nodes_1 + numparts(strSecond) + 2);
	
	int iter = strSecond.length();
	for (int i = 0; i < iter; i++) {
		mult(nFirst, nInter, strSecond[i] - '0');
		adjust(nInter);
		mult10(nTotal);
		adjust(nTotal);
		add(nTotal, nInter); //This call also resets nInter to zero
		adjust(nTotal);
	}
	string strBuffer = "";
	appendNumberToBuffer(nTotal, strBuffer);
	return removeLeadingZeros(strBuffer);
}

Number * makeEmptyLinkedList(int numlinks)
{
	if (!numlinks) return 0;
	Number * nHead, * nTemp, * nOld;
	for (int i = 0; i < numlinks; i++) {
		nOld = nTemp;
		nTemp = new Number;
		if (!i) nHead = nTemp;
		else nOld->next = nTemp;
	}
	return nHead;
}
void fillLinkedList(Number * nHead, string strDigits)
{
	char * sDup = strdup(strDigits.c_str());
	strrev(sDup);
	
	for (int i = 0; nHead; i++, movenext(nHead)) {
		nHead->part = 0;
		for (int j = 0; j < PARTLENGTH; j++) {
			char chrLetterToAdd = sDup[(i * PARTLENGTH) + j];
			if (chrLetterToAdd == '\0') break;
			int intDigitToAdd = chrLetterToAdd - '0';
			nHead->part += intDigitToAdd * tenpower(j);
		}
	}
}
void movenext(Number * & nPointer)
{
	nPointer = nPointer->next;
}
int numparts(string strValue)
{
	int length = strValue.length();
	int total = length / PARTLENGTH;
	return (length % PARTLENGTH) ? total + 1 : total;
}
void adjust(Number * nList)
{
	int remain = 0;
	while (nList) {
		nList->part += remain;
		long divider = tenpower(PARTLENGTH);
		remain = nList->part / divider;
		nList->part %= divider;
		movenext(nList);
	}
}
void add(Number *nTotal, Number *nInter)
{
	while (nInter) {
		nTotal->part += nInter->part;
		nInter->part = 0;
		movenext(nTotal);
		movenext(nInter);
	}
}
void mult10(Number * nList)
{
	while (nList) {
		nList->part *= 10;
		movenext(nList);
	}
}
void mult(Number * nOperand, Number * nResult, long number)
{
	while (nOperand) {
		nResult->part = nOperand->part * number;
		movenext(nOperand);
  		movenext(nResult);
	}
}
long tenpower(int intExponent)
{
	return (long) pow(10.0, (double) intExponent);
}
string removeLeadingZeros(string strValue)
{
	int intNonZeroPos = strValue.find_first_of(string("123456789"));
	if (intNonZeroPos == string::npos) return string("0");
	else {
  		int intLength = strValue.length();
		return strValue.substr(intNonZeroPos, intLength - intNonZeroPos);
	}
}
void appendNumberToBuffer(Number * nHead, string & strBuffer)
{
	if (nHead->next) appendNumberToBuffer(nHead->next, strBuffer);
 	char strPrintfFormat[10], strPartValue[10];
  	sprintf(strPrintfFormat, "%%0%dld\0", PARTLENGTH);
  	sprintf(strPartValue, strPrintfFormat, nHead->part);
  	strBuffer += strPartValue;
}