Thread: Numbers into English: Please grade me! - Jumping into C++ Chapter 7 Exercise 1

  1. #1
    Registered User
    Join Date
    Sep 2020
    Posts
    1

    Post Numbers into English: Please grade me! - Jumping into C++ Chapter 7 Exercise 1

    This took me far longer than it felt like it should have, but I completed it and it works for numbers -999,999 to 999,999 (as far as I can tell)

    The thing I had the most trouble with was figuring out how to separate the 'chunks', and I still feel like there was a more efficient way to do it that I simply don't know about (e.g. somehow using the find function instead of math to identify the digits, or getting a single function to return the two 'chunks' rather than duplicating it)

    I definitely learned a lot from this exercise, but I can't help but feel I over-complicated it several steps along the way. Please give harsh criticism where you think I can improve!



    Code:
    #include <iostream>#include <string>
    #include <cmath>
    
    
    using namespace std;
    
    
        int input;
        int chunk1; //these are global because they're accessed by multiple functions
        int chunk2;
    
    
    int main()
    {
        string finalResult;
        string generateChunkText(int a);
        string textChunk1="";
        string textChunk2="";
        bool isNegative=false;
        bool isThousand=false;
    
    
        cout << "Please enter a number between -999,999 and 999,999.\n";
        cin >> input;
    
    
    //various checks minimized for clearer thinking
        if (input == 0)
        {
            cout << "zero";
            return 0;
        }
        if (input < 0)
        {
            isNegative=true;
            input = input*-1;
        }
        if (input > 999)
        {
            isThousand=true;
        }
        if (input > 999999)
        {
            cout << "nope.\n";
            return 0;
        }
        int numbersInChunk1(int chunk1);   //breaks the number into 2 3 digit chunks and returns the values to chunk 1 and 2 so they can be sent to generateChunkText that way.
        int numbersInChunk2(int chunk2);
        chunk1=numbersInChunk1(input);
        chunk2=numbersInChunk2(input);
    
    
        textChunk1=generateChunkText(chunk1); //function that writes the text of a given 1-3 digit input
        textChunk2=generateChunkText(chunk2);
    
    
        if (isThousand==true)
        {
            textChunk2 = textChunk2 + "thousand ";
        }
        finalResult=textChunk2+textChunk1;
        if (isNegative==true)
        {
            finalResult = "negative "+ finalResult;
        }
    
    
        cout << "Converted into English, your number is:\n"<<finalResult<<"\n";
    }
    
    
    string generateChunkText(int someChunk)
    {
                bool isOnes=false;
                bool isTens=false;
                bool isHundreds=false;
                bool isBelowNineteen=false; //I found that things broke if I didn't set all these variables in the highest scope of this function, but I don't fully know why
                int howManyOnes=0;
                int howManyTens=0;
                int howManyHundreds=0;
                int howManyTensNineteen=0;
    
    
                string result;
    
    
                int n1;
                int n2;
                int n3;
                n3 = someChunk%10;
                someChunk /= 10;
                n2 = someChunk%10;
                someChunk /= 10;
                n1 = someChunk%10;
                someChunk /= 10;
                if ((n2 == 1) || (n2 == 0))
                {
                    isBelowNineteen=true; //returns if the tens/one slot has 19 and below
                }
                if (n1 != 0)
                {
                    isHundreds=true; //returns true if the hundreds slot isn't 0
                }
                if (n2 != 0)
                {
                    isTens=true; 
                }
                if (n3 != 0)
                {
                    isOnes=true; 
                }
    
    
                if (isHundreds==true)
                {
    
    
                    string hundredsText;
                    howManyHundreds = n1;
                    switch (howManyHundreds)
                    {
                    case 0: hundredsText="";
                    case 1: hundredsText="one hundred ";  result=hundredsText+result;     break;
                    case 2: hundredsText="two hundred ";  result=hundredsText+result;     break;
                    case 3: hundredsText="three hundred "; result=hundredsText+result;    break;
                    case 4: hundredsText="four hundred "; result=hundredsText+result;    break;
                    case 5: hundredsText="five hundred "; result=hundredsText+result;    break;
                    case 6: hundredsText="six hundred "; result=hundredsText+result;     break;
                    case 7: hundredsText="seven hundred "; result=hundredsText+result;   break;
                    case 8: hundredsText="eight hundred "; result=hundredsText+result;   break;
                    case 9: hundredsText="nine hundred "; result=hundredsText+result;    break;
                    default: cout << "error at hundredsText chunk1\n";  return 0;
                    }
                }
                if ((isTens==true) && (isBelowNineteen==false))
                {
                    string tensText;
                    howManyTens = n2; 
                    switch (howManyTens)
                    {
                    case 0: tensText="";
                    case 2: tensText="twenty ";    result=result+tensText; break;
                    case 3: tensText="thirty ";    result=result+tensText; break;
                    case 4: tensText="forty ";    result=result+tensText; break;
                    case 5: tensText="fifty ";    result=result+tensText; break;
                    case 6: tensText="sixty ";    result=result+tensText; break;
                    case 7: tensText="seventy ";    result=result+tensText; break;
                    case 8: tensText="eighty ";    result=result+tensText; break;
                    case 9: tensText="ninety ";    result=result+tensText; break;
                    default: cout << "error at tensText chunk1\n"; return 0;
                    }
                }
    
    
                       if ((isOnes==true)&&(isBelowNineteen==false))
                            {
                                string onesText;
                                howManyOnes = n3;
                                switch (howManyOnes)
                                {
                                case 0: onesText="";    result=result+onesText; break;
                                case 1: onesText="one ";    result=result+onesText; break;
                                case 2: onesText="two ";    result=result+onesText; break;
                                case 3: onesText="three ";    result=result+onesText; break;
                                case 4: onesText="four ";    result=result+onesText; break;
                                case 5: onesText="five ";    result=result+onesText; break;
                                case 6: onesText="six ";    result=result+onesText; break;
                                case 7: onesText="seven ";    result=result+onesText; break;
                                case 8: onesText="eight ";    result=result+onesText; break;
                                case 9: onesText="nine ";    result=result+onesText; break;
                                default: cout << "error at onesText chunk1\n"; return 0;
                                }
                            }
                if (isBelowNineteen==true)
                {
                    string tensTextNineteen;
                    string tensDigit = to_string(n2);
                    string onesDigit = to_string(n3);
                    string nineteenDigit = tensDigit+onesDigit;
                    howManyTensNineteen = stoi(nineteenDigit);
    
    
                    switch (howManyTensNineteen)
                    {
                    case 0: tensTextNineteen="";    result=result+tensTextNineteen; break;
                    case 1: tensTextNineteen="one ";    result=result+tensTextNineteen; break;
                    case 2: tensTextNineteen="two ";    result=result+tensTextNineteen; break;
                    case 3: tensTextNineteen="three ";    result=result+tensTextNineteen; break;
                    case 4: tensTextNineteen="four ";    result=result+tensTextNineteen; break;
                    case 5: tensTextNineteen="five ";    result=result+tensTextNineteen; break;
                    case 6: tensTextNineteen="six ";    result=result+tensTextNineteen; break;
                    case 7: tensTextNineteen="seven ";    result=result+tensTextNineteen; break;
                    case 8: tensTextNineteen="eight ";    result=result+tensTextNineteen; break;
                    case 9: tensTextNineteen="nine ";    result=result+tensTextNineteen; break;
                    case 10: tensTextNineteen="ten ";    result=result+tensTextNineteen; break;
                    case 11: tensTextNineteen="eleven ";     result=result+tensTextNineteen; break;
                    case 12: tensTextNineteen="twelve ";    result=result+tensTextNineteen; break;
                    case 13: tensTextNineteen="thirteen ";    result=result+tensTextNineteen; break;
                    case 14: tensTextNineteen="fourteen ";    result=result+tensTextNineteen; break;
                    case 15: tensTextNineteen="fifteen ";    result=result+tensTextNineteen; break;
                    case 16: tensTextNineteen="sixteen ";    result=result+tensTextNineteen; break;
                    case 17: tensTextNineteen="seventeen ";    result=result+tensTextNineteen; break;
                    case 18: tensTextNineteen="eighteen ";    result=result+tensTextNineteen; break;
                    case 19: tensTextNineteen="nineteen ";    result=result+tensTextNineteen; break;
                    default: cout << "error at tensTextNineteen chunk1";
                    }
                }
            return result;
    }
    
    
    int concat(int a, int b, int d)
    {
    
    
        string s1 = to_string(a); //converts each int to strings
        string s2 = to_string(b);
        string s3 = to_string(d);
        string s = s1 + s2 + s3; //combines said strings
        int c = stoi(s); //makes said string an integer again
        return c; //returns said integer
    
    
    }
    
    
    int numbersInChunk1(int input)
    {
    int n1=0,n2=0,n3=0,n4=0,n5=0,n6=0;
    int chunk1;
    int mockInput;
    mockInput=input; //this probably isn't necessary, but I might need to check input's value later, so I don't want to modify it.
    
    
        n6 = mockInput%10;
        mockInput /= 10;
        n5 = mockInput%10;
        mockInput /= 10;
        n4 = mockInput%10;
        mockInput /= 10;
        n3 = mockInput%10;
        mockInput /=10;
        n2 = mockInput%10;
        mockInput /= 10;
        n1 = mockInput%10;
        mockInput /= 10;
    
    
        chunk1 = concat(n4, n5, n6);
    }
    int numbersInChunk2(int input)
    {
    int n1=0,n2=0,n3=0,n4=0,n5=0,n6=0;
    int chunk2;
    int mockInput;
    mockInput=input;
    
    
        n6 = mockInput%10;
        mockInput /= 10;
        n5 = mockInput%10;
        mockInput /= 10;
        n4 = mockInput%10;
        mockInput /= 10;
        n3 = mockInput%10;
        mockInput /=10;
        n2 = mockInput%10;
        mockInput /= 10;
        n1 = mockInput%10;
        mockInput /= 10;
    
    
        chunk2 = concat(n1, n2, n3);
    }

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,553
    For starters, global variables are usually considered a bad practice, learn to pass those variables to and from the functions that need them.

    Initialize your variables when you declare them. And declare the variables close to first use, not in one big glob at the beginning of some scope.

    Don't place multiple statements on one line, this will make debugging your code much harder.

    Too many meaningless variable and function names. Use meaningful variable and function names.

    You have some variables that are duplicated by another variable, why? ie: "howManyHundreds = n1;" wouldn't it just be easier if you just used howManyHundreds?

    Much too much code duplication. For example what is the difference between the numbersInChunks() functions, other than the variable names? It appears to me that you really should only need one of those functions.

    Consider std::vector/arrays to hold the "English numbers" then you probably wouldn't need those switch statements.

    ie:
    Code:
         if(howManyHundreds != 0)
        {
            string hundredsText[] = {"zero", "one", "two", "three", "four", "five",
                                     "six", "seven", "eight", "nine"};
            result = hundredsText[howManyHundreds] + " hundred ";
        }
    Your indentation needs serious work. Consistent indentation will make your code much easier to read.

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    441
    The only strings you should have in the program are the digits 0-9, the special cases "eleven", "twelve", and "thirteen", the suffix "teen", the special cases "ten", "twenty", "thirty", "forty,""fifty", the suffix "ty", "hundred", "thousand", and "and". You only use "zero" for the special case of 0. And "minus" if you are dealing with negatives, but that's a trivial extension.

    Essentially you need to build up the number from fragments. If it is zero, special case it. If it is one digit, the digit number. If it is >= 10 and < 20, special case it again. It it is >=20 and < 100, the tens string, followed by the digit string (remembering that we don't add anything for zero). If it is > 100 and < 1000, divide by 100 to give you a digit string, add "hundred", then take modulus 100 and add the string for numbers < 100. If it is >= 1000, divide by a thousand to give you a number below a thousand, get the string, add "thousand", then take modulus 1000, and add the string for number < 1000.

    You need to be careful about "and".
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 08-11-2016, 05:50 AM
  2. Replies: 3
    Last Post: 08-04-2016, 05:35 AM
  3. Jumping into C++ Chapter 14, exercise 6.
    By CppProgrammer88 in forum C++ Programming
    Replies: 5
    Last Post: 04-12-2016, 07:27 PM
  4. Replies: 6
    Last Post: 08-20-2012, 07:09 AM

Tags for this Thread