Infinite output when I print a variable inside a loop

May 8, 2018 at 3:03pm
I'm trying to convert a number input to words. I am a beginner so my code might look clunky. I also apologise for posting such a large code. The loop at the "String Construction" section crashes and is printing infinite values of the variable q (quotient). I have also tried printing a simple variable like flag = 1 before q and that too is giving infinite 1s. I cannot figure out what is causing this. Any input would be greatly helpful for my learning!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>

using namespace std;

int main()
{
int i = 0, number = 0;
string num_name = "";
cout << "Enter a number (maximum value is 1,000,000,000)" << endl;
cin >> number;

//To find the maximum magnitude
while ((number / pow(10, i)) >= 1) 
{
    i++;
}
i--;
int j = i;
cout << j << endl; //Check

//To find which multiple of 3 i is
int n = 0;
while (j >= 3)
{
    if (j % 3 == 0) 
        n++;
    j--;
}
j = i;
cout << j << endl; //Check
cout << n << endl; //Check

//String construction
int k = n;
int q = 0;

while (k >= 1)
    {
    while (j >= (3*k))
    {
        q = (int)(number / pow(10, j));
        if (j == 2 + (3 * k))
        {
            if (q == 1) num_name += "one";
            else if (q == 2) num_name += "two";
            else if (q == 3) num_name += "three";
            else if (q == 4) num_name += "four";
            else if (q == 5) num_name += "five";
            else if (q == 6) num_name += "six";
            else if (q == 7) num_name += "seven";
            else if (q == 8) num_name += "eight";
            else if (q == 9) num_name += "nine";

            num_name += "hundred";
        }
        if (j == 1 + (3 * k)) 
            continue;
        if (j == 3 * k)
        {
            if (q == 1) num_name += "one";
            else if (q == 2) num_name += "two";
            else if (q == 3) num_name += "three";
            else if (q == 4) num_name += "four";
            else if (q == 5) num_name += "five";
            else if (q == 6) num_name += "six";
            else if (q == 7) num_name += "seven";
            else if (q == 8) num_name += "eight";
            else if (q == 9) num_name += "nine";
            else if (q == 10) num_name += "ten";
            else if (q == 11) num_name += "eleven";
            else if (q == 12) num_name += "twelve";
            else if (q == 13) num_name += "thirteen";
            else if (q == 14) num_name += "fourteen";
            else if (q == 15) num_name += "fifteen";
            else if (q == 16) num_name += "sixteen";
            else if (q == 17) num_name += "seventeen";
            else if (q == 18) num_name += "eighteen";
            else if (q == 19) num_name += "nineteen";
            if (q >= 20 && q <= 99)
            {
                int r = 0;
                r = q % 10;
                (int)(q /= 10);
                if (q == 2) num_name += "twenty";
                else if (q == 3) num_name += "thirty";
                else if (q == 4) num_name += "forty";
                else if (q == 5) num_name += "fifty";
                else if (q == 6) num_name += "sixty";
                else if (q == 7) num_name += "seventy";
                else if (q == 8) num_name += "eighty";
                else if (q == 9) num_name += "ninety";

                if (r == 1) num_name += "one";
                else if (r == 2) num_name += "two";
                else if (r == 3) num_name += "three";
                else if (r == 4) num_name += "four";
                else if (r == 5) num_name += "five";
                else if (r == 6) num_name += "six";
                else if (r == 7) num_name += "seven";
                else if (r == 8) num_name += "eight";
                else if (r == 9) num_name += "nine";
        }


            if (k == 3) num_name += "billion";
            else if (k == 2) num_name += "million";
            else if (k == 1) num_name += "thousand";
    }
    number = number % (int)pow(10, j);
    j--;
    }
    k--;
}
cout << num_name << endl;
cin.ignore();
cin.get();
return 0;
}
May 8, 2018 at 4:39pm
for something like this, wouldn't you rather have a Stack and analyze the number from right to left, pushing words onto the top? 1,234,567

"seven"
"sixty-seven"
"five hundred sixty-seven"
"four thousand five hundred sixty-seven"
"thirty-four thousand five hundred sixty-seven"
"two hundred thirty-four thousand five hundred sixty-seven"
"one million two hundred thirty-four thousand five hundred sixty-seven"

For this same number with your current code, I'm getting i, j, n outputs of 6, 6, 2. Is this expected so far?
May 8, 2018 at 4:49pm
> my code might look clunky
proper indentation makes wonders

> cin >> number;
your program ask for input
different inputs may provide different results, so you should gives us an example that does cause the issue.

1
2
3
4
5
6
7
8
9
10
11
12
	while(k >= 1) {
		while(j >= (3 * k)) {
			q = (int)(number / pow(10, j));
			if(j == 2 + (3 * k)) {
				//...
			}
			if(j == 1 + (3 * k))
				continue; // <---
			//...
		}
		k--;
	}
suppose that you reach the continue line, there is nothing in the code that changes `k' or `j', so the condition of the loop will not modify and then you got an infinete loop
May 8, 2018 at 5:30pm
I didn't know I had to include j--; before the continue. And I got to know about switch case just a few moments ago. I'm gonna edit the code to make it more readable by making functions. Thank you all for your help!
Last edited on May 8, 2018 at 5:33pm
May 8, 2018 at 6:58pm
Hi jkp993,

In case you get curious about std::stack in the future, I think I've got an implementation.

Takeaways:
- avoid doing user input while improving your algorithm; it'll slow you down and you can toss more stuff at it with an array of examples
- try to put reusable strings as const or in const arrays; easier to both reuse and maintain
- comments can help explain unusual bits or variable declarations at a glance

Good luck.

visual representation of number and indices (from right) to show you my approach and pattern
    1, 2 3 4 , 5 6 7
    
i = 6  5 4 3   2 1 0


Stack example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <vector>

using namespace std;

const string F20[] = {"", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};

const string TENS[] = {"", "", "twenty", "thirty", "forty", "fifty", "sixty",
"seventy", "eighty", "ninety"};

const string HUN = "hundred";

const string THOU[] = {"", "thousand", "million", "billion", "trillion"};

string NumToWords(long n)
{
    if (n==0) { return "zero"; }
    int prev_d = n%10; // Previous digit, esp. for stuff like 'twelve'
    stack<string> st;
    st.push(F20[prev_d]);
    n /= 10;
    
    int d;      // Current digit
    int i = 1;  // Index from the right
    while (n)
    {
        d = n%10;
        if ( i%3 == 0 )  // thousands
        {
            if (d>=1)
            {
                st.push(THOU[i/3]);
                st.push(F20[d]);
            }
        }
        else if ( (i+1)%3 == 0 ) // hundreds
        {
            if (d>=1)
                st.push(F20[d] + " " + HUN);
        }
        else  // tens
        {
            if (d==1)
            {
                st.pop();
                st.push(F20[10+prev_d]);
            }
            else if (d>1)
            {
                st.push(TENS[d] + "-");
            }
        }
        prev_d = d;
        n/=10;
        i+=1;
    }
    
    // Build string, adding space if top doesnt end in a dash
    ostringstream oss;
    while (!st.empty())
    {
        string& top = st.top();
        oss << top;
        if (top.back() != '-')
            oss << ' ';
        st.pop();
    }
    return oss.str();
}

int main()
{
    vector<long> numbers =
    {
        0,
        11,
        33,
        16000,
        1234567,
        1000004,
        1012009,
        1000000000000,
        123000014000200
    };
    for (auto& n : numbers)
        cout << n << ": " << NumToWords(n) << endl;
}


Can test at https://repl.it/repls/LoyalVengefulVaporware

0: zero
11: eleven 
33: thirty-three 
16000: sixteen thousand  
1234567: one million two hundred thirty-four thousand five hundred sixty-seven 
1000004: one million four 
1012009: one million twelve thousand nine 
1000000000000: one trillion  
123000014000200: one hundred twenty-three trillion fourteen million two hundred  

Topic archived. No new replies allowed.