Here is my program that turns numbers into text.  It can be extended to millions, billions, trillions and so on. Please review my code and here is what I expect from the users:Is there any better variable names, function names, you can give me? Or my given names are okay? If you've better variable name ideas, please share.Last time one expert user gave me suggestion to write functions in separate files and then implement into main function by calling header name, I just did that, is this okay? Or I should make more separate files for each custom function?I tried my best to write program in object oriented way. I used Class and then wrote some functions inside them so I can call any method after the object name.For example: number.validate(varName)Do you see any problems in that? Am I doing something that isn't a good programming practice?My program works perfectly without any problem, is there any better way to do this?1. main.cpp/* * Implement the source code that turns numbers into English text. */#include <iostream>#include numberToText.hppint main (void){    numberToText();    return 0;}2. numberToText.cpp#include <iostream>#include <string>#include textlib.hppclass num{    public:        bool validate (std::string numStr)            {            for (int i = 0; i < numStr.length(); i++)                {                    if (!(isdigit(numStr[i])))                    {                        return false;          // terminate loop by returning value if there's anything in this string apart from number                    }                }            return true; // if there is no problem in loop then return true to confirm that string has all the numbers.            }        void take (std::string &numberString)            {                std:: cout << Enter your number:\n;                std::cin   >> numberString;                while (1)                {                    if (validate(numberString))                    {                        break; //SUCCESS                    }                    else                    {                        std::cout << Invalid number, try again:\n;                        std::cin  >> numberString;                    }                }            }        void text (std::string string)            {                int digitLength = string.length();                if      (digitLength == 1)                {                    one_Nine(0, string);                }                else if (digitLength == 2)                {                    twoDigits(0, string);                }                else if (digitLength == 3)                {                    threeDigits(0, string);                }                else if (digitLength > 3 && digitLength < 7)                {                    thousand(0, string, digitLength);                }                else  // add more conditions if you want to extend the program                {                    std::cout << Sorry, that's a vary large number.\n;                }            }    private:};void numberToText (void){    std::string numStr;    num number;    number.take(numStr);    number.validate(numStr);    number.text(numStr);}3. numberToText.hpp/* * take numbers and display text */#ifndef NUMBERTOTEXT_HPP_#define NUMBERTOTEXT_HPP_void numberToText (void);#endif4. textlib.cpp#include <iostream>#include <string>#include textlib.hppvoid one_Nine (int i, std::string numberString){    if      (numberString[i] == '1')    {        std::cout << One ;    }    else if (numberString[i] == '2')    {        std::cout << Two ;    }    else if (numberString[i] == '3')    {        std::cout << Three ;    }    else if (numberString[i] == '4')    {        std::cout << Four ;    }    else if (numberString[i] == '5')    {        std::cout << Five ;    }    else if (numberString[i] == '6')    {        std::cout << Six ;    }    else if (numberString[i] == '7')    {        std::cout << Seven ;    }    else if (numberString[i] == '8')    {        std::cout << Eight ;    }    else if (numberString[i] == '9')    {        std::cout << Nine ;    }    else if      (numberString[0] == '0')    {        std::cout << Zero\n;    }    else    {        std::cout << Error: one_Nine() function isn't working!\n;    }}void twoDigits (int j, std::string numberString){    if      (numberString[j] == '1')    {        if      (numberString[j+1] == '0')        {            std::cout << Ten ;        }        else if (numberString[j+1] == '1')        {            std::cout << Eleven ;        }        else if (numberString[j+1] == '2')        {            std::cout << Twelve ;        }        else if (numberString[j+1] == '3')        {            std::cout << Thirteen ;        }        else if (numberString[j+1] == '4')        {            std::cout << Fourteen ;        }        else if (numberString[j+1] == '5')        {            std::cout << Fifteen ;        }        else if (numberString[j+1] == '6')        {            std::cout << Sixteen ;        }        else if (numberString[j+1] == '7')        {            std::cout << Seventeen ;        }        else if (numberString[j+1] == '8')        {            std::cout << Eighteen ;        }        else if (numberString[j+1] == '9')        {            std::cout << Nineteen ;        }        else        {            std::cout << Error: twoDigits().\n;        }    }    else if (numberString[j] == '2')    {        std::cout << Twenty ;        if (numberString[j+1] == '0')            {                std::cout << ;            }        else        {            one_Nine(j+1, numberString);        }    }    else if (numberString[j] == '3')    {        std::cout << Thirty ;        if (numberString[j+1] == '0')            {                std::cout << ;            }        else        {            one_Nine(j+1, numberString);        }    }    else if (numberString[j] == '4')    {        std::cout << Forty ;        if (numberString[j+1] == '0')            {                std::cout << ;            }        else        {            one_Nine(j+1, numberString);        }    }    else if (numberString[j] == '5')    {        std::cout << Fifty ;        if (numberString[j+1] == '0')            {                std::cout << ;            }        else        {            one_Nine(j+1, numberString);        }    }    else if (numberString[j] == '6')    {        std::cout << Sixty ;        if (numberString[j+1] == '0')            {                std::cout << ;            }        else        {            one_Nine(j+1, numberString);        }    }    else if (numberString[j] == '7')    {        std::cout << Seventy ;        if (numberString[j+1] == '0')            {                std::cout << ;            }        else        {            one_Nine(j+1, numberString);        }    }    else if (numberString[j] == '8')    {        std::cout << Eighty ;        if (numberString[j+1] == '0')            {                std::cout << ;            }        else        {            one_Nine(j+1, numberString);        }    }    else if (numberString[j] == '9')    {        std::cout << Ninety ;        if (numberString[j+1] == '0')            {                std::cout << ;            }        else        {            one_Nine(j+1, numberString);        }    }    else if (numberString[j] == '0')    {        one_Nine(j+1, numberString);    }    else    {        std::cout << Error: **********^^*****************;    }}void threeDigits (int k, std::string numberString){    if (numberString[k] != '0')    {        one_Nine(k, numberString);        std::cout << Hundred ;    }    if (numberString[k+1] != '0' || numberString[k+2] != '0')    {        twoDigits(k+1, numberString);    }}void thousand (int l, std::string numberString, int digitLength){    if      (digitLength == 4)    {        if (numberString[l] != '0')        {            one_Nine(l, numberString);            std::cout << Thousand ;        }        threeDigits(l+1, numberString);    }    else if (digitLength == 5)    {        if (numberString[l] != '0')        {            twoDigits(l, numberString);            std::cout << Thousand ;        }        else if (numberString[l] == '0' && numberString[l+1] != '0')        {            one_Nine(l, numberString);            std::cout << Thousand ;        }        else        {            std::cout << ;        }        threeDigits(l+2, numberString);    }    else if (digitLength == 6)    {        if      (numberString[l] != '0')        {            threeDigits(l, numberString);            std::cout << Thousand ;        }        else if (numberString[l] == '0' && numberString[l+1] != '0')        {            twoDigits(l+1, numberString);            std::cout << Thousand ;        }        else if (numberString[l+2] != '0')        {            one_Nine(l+2, numberString);            std::cout << Thousand ;        }        else        {            std::cout << ;        }        threeDigits(l+3, numberString);    }    else    {        std::cout << Error: ~~~~~~;    }}5. textlib.hpp/* * Can print numbers in English text. */#ifndef TEXTLIB_HPP_#define TEXTLIB_HPP_void one_Nine (int i, std::string numberString);void twoDigits (int j, std::string numberString);void threeDigits (int k, std::string numberString);void thousand (int l, std::string numberString, int digitLength);#endif
Turning numbers into text
c++;converting
C++ vs C styleIn C++ you don't need to declare empty parameter lists as void. Replace int int main (void)by int main()You also don't need to return 0; at the end of main in C++. This is done automatically by the compiler if the end of the main function is reached.Class designUsing a class in this context was not the best choice. When you look at your class you will notice that it has no member variables and only member functions.This means that each function could have been declared static (which means it does not need an instance of this class to be called on). If you were to make this transformation (making all of these class member functions static) you would have another code smell: A class that contains no (per instance) data and only static functions should in fact be a namespace.Applying this transformation would only change your code in numberToText to:            std::string numStr;            num::take(numStr);            num::validate(numStr);            num::text(numStr);Function (signature) designYou clearly need to use the return values of functions!Let's have a look at num::take for example. It returns the value via a reference parameter and has the return type void. This is somewhat counterintuitive. When looking at a function and asking oneself what it returns the first look is for the return type which says void in your case. How about this function interface:std::string take();It clearly communicates that take returns a string. Looking at the previous calls take(string) looks like it is taking the string and doing something with it (rather than returning into it).The name take seems a bit generic to me. What is taken? What the function actually does is querying the user for a valid number(string) until one is given. The name should reflect that. How about getNumberStringFromUser or something similar?Don't break your loop unnecessarilyLooking at the code I wonder why you are using a break here:while (1){    if (validate(numberString))    {        break; //SUCCESS    }//...Use the loop condition instead of breaking from the loop if it is more clear:while (!validate(numberString)){Exiting the loop within its body forces the reader to understand the additional (unexpected) branch introduced at the break.redundant validationThe string has already been validated in take so why validating it again and then discarding the return value of validate?function namesThe names of some functions are not well chosen:one_Nine ->  printOnesDigitWordtwoDigits -> printTensDigitWordthreeDigits -> printHundredsDigitWordthousand -> printNumberAsWordsAlgorithmYour code looks very brittle and not that extensible. The interfaces of the printing functions are a bit complicated. Instead of passing the full number string and the index where to look you should pass only the part of the string that is relevant to the function. Another possibility would be to pass the value as an int. This would allow you to fit the function more easily (and portable) into arrays for example one_Nine:std::string oneDigitToString(int digit){    assert(0 <= digit && digit < 10);    static const char *digitNames[] = {Zero One, Two, Three, Four,                                        Five, Six, Seven, Eight, Nine };    return digitNames[digit];}Note that there are several improvements:reduced sideeffects by not calling std::cout (but now the caller has to print!)increased efficiency (you always get the result in one step instead of hopping through the cascading ifs)tighter interface (there are less wrong values that you can pass into this function)stricter error reporting: the assert enforces correct values being passed to the function. Breaking the assert condition gives a (runtime) error and tells the developer that it is the callers fault (assert guards preconditions!)Side effectsIn the previous example I have returned the digit word string instead of printing it to std::cout this reduces side effects and increases the reusability of the function. Lets say you want to have a GUI version of this program where the string is not presented on cout but in the window title. Using functions that return the result as a string makes this easy while using cout makes it hard (you would have to duplicate or rewrite the code).