# Converting Numbers to Words

Printable View

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 09-02-2003
denizengt
Converting Numbers to Words
Hello everyone.

I'm new to programming in general, and I'm wondering if you can help me.

Does anyone have a solution to a problem where you are given a number, lets say, 1645030, and have to produce the output: one million six hundred forty five thousand thirty?

I have a partially working solution that works for numbers 1000 and less but it's very clunky and doesn't work when I extend it (massive confusing mass of if's). Does anyone have a neater, working way of doing it? Much appreciated!

I'm just learning c as a hobby, and this has stopped me in my tracks! :D
• 09-03-2003
DavT
denizengt,

I suggest that you post what you have written so far, then we can help you restructure it so that it is (hopefully) less clunky. We will also be able to give you some pointers on extending the structure to cope with larger numbers. This is a much better way for you to learn than just looking at an answer you are given...
• 09-03-2003
denizengt
Ok DavT, thank you for replying. Apologies to everyone on the size!
Code:

```#include <stdio.h> #include <strings.h>   void hasTrillions(char);   void hasBillions(char);   void hasMillions(char);   void hasThousands(char);   void hasHundreds(char);    void simpleNumber(char);   void hasTeen(char);   void hasTens(char);   main() {     /*Define string, and array of chars..*/         char string[256]; /*max length 255*/         int cPos;       int iterator;             printf("Enter an integer, and hit enter  :  ");       gets(string);       int len = strlen(string);       cPos = len;         for(iterator = 0; iterator != len; iterator++) {               if (cPos == 1){                 if(string[0] == '0') {                   printf("zero ");                   }                 simpleNumber(string[len-1]);                 cPos=0;         }               if(cPos == 2) {                     if (string[len-cPos] == '1'){               hasTeen(string[len-cPos+1]);               cPos=0;               break;}                         else if(string[len-cPos]!='1'){               hasTens(string[len-cPos]);               cPos--;             }                 }         if(cPos == 3) {           hasHundreds(string[len-cPos]);           cPos--;           }         if (cPos == 4) {           hasThousands(string[len-cPos]);           cPos--;           }         if (cPos == 5) {             if (string[len-cPos] == '1'){               hasTeen(string[len-cPos+1]);               cPos = cPos-2;               printf("Thousand ");             }                         if(string[len-cPos]!='1' ){               hasTens(string[len-cPos]);                 if(string[len-cPos] == '0'){                 printf("Thousand ");                 }               cPos--;             }           }         if (cPos == 6) {           if(string[len-cPos] != '0'){             hasHundreds(string[len-cPos]);             }             cPos--;           }         if (cPos > 6) {           switch(len){             case 7: hasMillions(string[0]);cPos--; break;             case 8: if(string[0] == '1'){                     hasTeen(string[1]);                     printf("Million ");                     cPos=cPos-2;                     break;                     }                     if(string[0] != '1'){                     hasTens(string[0]);                     cPos--;                     break;                     }                     break;             case 9:  break;             }           }       }     }   void hasTens(char x){       switch(x){         case '1':printf("Ten ");             break;         case '2':printf("Twenty ");             break;         case '3':printf("Thirty ");             break;         case '4':printf("Fourty ");             break;         case '5':printf("Fifty ");             break;         case '6':printf("Sixty ");             break;         case '7':printf("Seventy ");             break;         case '8':printf("Eighty ");             break;         case '9':printf("Ninety ");             break;       }   }   void hasTeen(char x){       switch(x){         case '0':printf("Ten");             break;         case '1':printf("Eleven ");             break;         case '2':printf("Twelve ");             break;         case '3':printf("Thirteen ");             break;         case '4':printf("Fourteen ");             break;         case '5':printf("Fifteen ");             break;         case '6':printf("Sixteen ");             break;         case '7':printf("Seventeen ");             break;         case '8':printf("Eighteen ");             break;         case '9':printf("Nineteen ");             break;       }   }   void simpleNumber(char n){       switch(n){         /* case '0':printf("Zero ");*/         case '1':printf("One ");             break;         case '2':printf("Two ");             break;         case '3':printf("Three ");             break;         case '4':printf("Four ");             break;         case '5':printf("Five ");             break;         case '6':printf("Six ");             break;         case '7':printf("Seven ");             break;         case '8':printf("Eight ");             break;         case '9':printf("Nine ");             break;       }   }   void hasHundreds(char x){       if(x !='0'){         simpleNumber(x);         printf("Hundred ");       }   }   void hasThousands(char x){       if(x !='0'){         simpleNumber(x);         printf("Thousand ");       }   }   void hasMillions(char x){       if(x !='0'){         simpleNumber(x);         printf("Million ");       }   }   void hasBillions(char x){       if(x !='0'){         simpleNumber(x);         printf("Billion ");       }   }   void hasTrillions(char x){       if(x !='0'){         simpleNumber(x);         printf("Trillion ");       }   }```
As you can see, it's pretty terrible! Someone said that I might improve it by using pointers. I'm not familiar with pointers (my first language was Java, and I'm not exactly excellent with that). Why should I use pointers? (sorry if this is really obvious to you!)

If you compile and build it..yeah, extension is a little bit of a problem.

Any pointers (not c pointers) ?
• 09-03-2003
Hammer
• 09-03-2003
denizengt
I must admit, I found those two links incredibly confusing.
• 09-03-2003
Prelude
>I must admit, I found those two links incredibly confusing.
Any reasonable solution to this problem is likely to be confusing. Especially if you're relatively new to the language. What parts are you having trouble with? Perhaps we can help.
• 09-03-2003
denizengt
Pointers! I can recognize pointers, but I'm not sure why one would use them over say, using variables for the purpose (especially in the context of arrays).

What are the benefits of using pointers in my case?
• 09-04-2003
Prelude
>What are the benefits of using pointers in my case?
Pointers simplify string operations. I find it easier to search, move around a string, and make signifigant changes when I'm using a pointer as the iterator. Integer indices just make complicated operations more opaque. Most of the string functions in the standard library also return pointers.
• 09-05-2003
denizengt
Ok, there's a question I've got to ask.

I don't think that the way I am trying to do it, ie, with functions, is perhaps the best method to do it. What I want to do, is convert numbers into words, and words into numbers, so it's to be a two way thing.

I read a little information on the web on "lookup" tables. That is, essentially arrays of strings. An earlier post on this website suggested to use them, however I'm not sure how I could "split" a number, say 76328, then use a lookup table to "tack" on a number descriptor, say "thousand" or "hundred" at the proper interval.

I apologise if I am not making much sense.
• 09-05-2003
Prelude
>I'm not sure how I could "split" a number
It's probably going to be easier to convert the number into a string using sprintf and then walk the string and print out the word value. Let's say you have 76328. You start on the left so that everything prints out nicely. 7 is the ten thousands place, so you print out "seventy" since 7 is equivalent to the tens place. Then you move forward to the thousands place and print "six", then "thousand". Move forward to the hundreds place and print the value of the digit, "three", then the value of the place, "hundred". Move forward to the tens place and print "twenty", then forward again to the ones place and print "eight". The result is "seventy six thousand three hundred twenty eight". Which is preciesly what you want. You'll notice a pattern here, the numbers pair into twos:

<tens> <ones>

Then you simply tack on further qualifiers after you handle the base cases: hundred, thousand, million, billion, etc... To convert to a number you perform the same process, this time using strcmp instead of testing a single character. For the actual implementation you could have a couple of tables such as one for the base cases and one for further qualifiers:
Code:

```struct digit {   const char *word[9];   int number[10]; }; struct digit base[] = {   /* Ones */   {     {"one", "two", "three", ..., "nine"},     {1,2,3, ... , 9},   },   /* Tens */   {     {"ten", "twenty", thirty", ...., "ninety"},     {10, 20, 30, ..., 90},   }, };```
Then you only have to handle the special case of the teens and use a counter to find the big stuff. Start at 0, increment to 1 and you're at the hundreds, increment to 2 and you're at the thousands. Lather, rinse, repeat.
• 09-07-2003
zahid
denizengt,
I don't know what you are thinking, But I would say the code in your second post is the simplest.
Which part is giving you the problem?

Code:

```........................ ......................... //Pattern for every 3 digit         if (cPos == 4) {           hasThousands(string[len-cPos]);           cPos--;           }         if (cPos == 5) {             if (string[len-cPos] == '1'){               hasTeen(string[len-cPos+1]);               cPos = cPos-2;               printf("Thousand ");             }                         if(string[len-cPos]!='1' ){               hasTens(string[len-cPos]);                 if(string[len-cPos] == '0'){                 printf("Thousand ");                 }               cPos--;             }           }         if (cPos == 6) {           if(string[len-cPos] != '0'){             hasHundreds(string[len-cPos]);             }             cPos--;           } ............................... .............................```
I guess you can make this code work.
• 09-08-2003
denizengt
Code:

``` struct digit {   const char *word[9];   int number[10]; }; struct digit base[] = {   /* Ones */   {     {"one", "two", "three", ..., "nine"},     {1,2,3, ... , 9},   },   /* Tens */   {     {"ten", "twenty", thirty", ...., "ninety"},     {10, 20, 30, ..., 90},   }, }```
Prelude, could you explain this code to me? This may sound stupid, but why is *word, a pointer?

Given a string is entered, how can I decide if it is literal, (and hence print out numerical equivalent from the struct), or if it is numerical(and hence print out literal from the struct?)
• 09-08-2003
Hammer
>>could you explain this code to me? This may sound stupid, but why is *word, a pointer?
word is an array of pointers, here is another example to help explain:
Code:

`const char *List[] = {"one", "two", "three" }`
The array is 3 elements in length, each element is sizeof(char*) in size. Each element is a pointer, pointing to a string literal, which is stored somewhere else in memory. The other was to code this is:
Code:

`const char List[][6] = {"one", "two", "three" }`
... but this way wastes memory, as the array now has 3 lots of 6*sizeof(char) in it. It is also more difficult to manage, because you are having to specify the maximum lenth of ny given element (6 in this case).

>>Given a string is entered, how can I decide if it is literal, (and hence print out numerical equivalent from the struct), or if it is numerical(and hence print out literal from the struct?) <<
If you can't convert it from a numeric, you'll have to assume its a literal and keep a tight control on the error checking.
• 09-08-2003
Prelude
>Given a string is entered, how can I decide if it is literal or if it is numerical
I gave some hackey code for this in another thread. It looked like so:
Code:

```char *endp; int num; num = (int)strtol(buff, &endp, 0); if (buff == endp)   /* Not a number */ else   /* Is a number */```
This chaffes a bit with me because if I have to perform such a test the program definition is grievously broken IMO.
• 09-09-2003
denizengt
I'm still unsure on how to tackle this problem

I've defined my struct similar to how Prelude did before.

Now, let's assume I am in "word to number mode". I get a string using gets(string)

I start from the left, and iterate through the each element in the string till it's end.

The parts I am still largely unsure about is writing the number out (after I convert the number contained in the string to the int).

How DO I determine when to tack on the qualifier? Say I enter 122,555 into the input string. I want this to say "one hundred twenty two thousand five hundred fifty five", I'm not sure how to use that struct object there, and when to tack on the qualifier..

I also want to reuse the code you see, so when I pass the literal version back, it will produce the numerical equivalent.

Sorry, I'm just really confused.. I expected this to be simpler..
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last