Вот другой способ.Не уверен в достоинствах по сравнению с памятью и скоростью, но легко добавить код для обработки большего количества цифр.
/* File : num_to_words_int.c
*
* Descr: Prints the equivalent number in words. '1' to 'one', etc.
* This version takes the input and converts it to a numeric vs.
* a string value. 345 vs. "345". Then uses modulus division to
* count the number of digits. The count represents the places;
* i.e. count=5 ==> 10,000 ,, 1,000 ,, 100 ,, 10 ,, 1 are the
* words that will be needed.
*
* 300 => count=3 ==>three hundred
* 30 => count=2 ==>thirtey
* 3 => count=1 ==>three
* 13 => count=2 ==>thirteen
* 3456 => count=4 ==>three thousand four hundred fifty six
*
* [345], [34 5], [3 4], [3, [0]
*
* Debugging Option:
* <run> num_to_words_int.exe number option_mask
*
* 001 - print init remainder array
* 010 - print filled remainder array
* 100 - print count, index, remainder value
*
* Author: Gene Bradshaw
* Date: 09-16-2016
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math>
void main(int argc, char *argv[])
{
const int HUNDREDS=0, THOUSANDS=1, MILLIONS=2, BILLIONS=3;
int i, count, total, remainder[12]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
long number=0, orignum=0;
char *ones[] = {"zero","one","two","three","four","five","six","seven","eight","nine"};
char *teens[] = {"ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"};
char *tens[] = {"ten","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};
char *places[] = {"hundred","thousand","million","billion"}; // place values; 10's, 100'2, etc.
// ERRORS ARGUMENTS
if(argc < 2)
{
printf("\na number is required as input!\n\n");
exit(1);
}
else if(argc > 3)
{
printf("\nonly one number and optionally a flag are required as input!\n\n");
exit(1);
}
else printf("\n");
// CONVERT TO WORDS
if(!(number = atol(argv[1]))) // zero
{
printf("number: %d\n%s\n\n", number, ones[0]);
exit(0);
}
// Debugging
if(argv[2] && (atoi(argv[2]) & 0x01))
{
for(i=11; i>-1; i--) printf("%d %d, ", i, remainder[i]);
printf("\n\n");
}
// GET DIGITS
if(number < 0) // Remeber if negative, then make positive
{
orignum = number; number *= -1;
}
count=0;
do{
remainder[count++] = number%10;
number/=10;
}while(number); // int type var converts to '0' when # < 0
// ERROR DIGIT COUNT
if (count > 12)
{
printf("\ntoo many digits; up to 12 digits supported!\n\n");
exit(1);
}
// Debugging
if(argv[2] && (atoi(argv[2]) & 0x02))
{
for(i=11; i>-1 ; i--) printf("%d %d, ", i, remainder[i]);
printf("\n\n");
}
// DISPLAY REMAINDERS
printf("number: "); // This if for displaying the reverse remainder[].
if (orignum < 0) printf("-");
for(i=count-1; i>-1; i--)
{
if(!(i%3) && i) printf("%d,", remainder[i]);
else printf("%d", remainder[i]);
}
printf("\n");
// FIND AND PRINT WORDS
total = count; i = count-1; // counting rules
if(orignum < 0) printf("negative ");
while(count)
{
if(argv[2] && (atoi(argv[2]) & 0x04)) // Debugging
printf("\nC: %d, i: %d and R: %d\n", count, i, remainder[i]);
switch(count)
{
case 1:
// print if not teens or 0
if(remainder[i+1] != 1 && remainder[i])
printf("%s ", ones[remainder[i]]);
break;
case 2:
// teens when 2nd digit is a '1'
if(remainder[i] == 1)
printf("%s ", teens[remainder[i-1]]);
// ones when 1st digit is not a '0'
else if(remainder[i])
printf("%s ", tens[remainder[i]]);
break;
case 3: // d
if(remainder[i]){
printf("%s ", ones[remainder[i]]);
printf("%s ", places[count-3]);
}
break;
case 4: // k
if(remainder[i])
printf("%s ", ones[remainder[i]]);
if(remainder[i] || (total > 4 && total < 7))
printf("%s ", places[count-3]);
break;
// 10,000 100,000 1,000,000
// ten tho hun tho one million
case 5: // 10 k
case 8: // 10 M
case 11: // 10 B
if(remainder[i]){ printf("%s ", tens[remainder[i]]); }
break;
case 6: // 100 k
case 9: // 100 M
case 12: // 100 B
if(remainder[i]){
printf("%s ", ones[remainder[i]]);
printf("%s ", places[HUNDREDS]);
}
break;
case 7: // M
if(remainder[i])
printf("%s ", ones[remainder[i]]);
if(remainder[i] || (total > 7 && total < 10))
printf("%s ", places[MILLIONS]);
break;
case 10: // B
if(remainder[i])
printf("%s ", ones[remainder[i]]);
if(remainder[i] || (total > 10 && total < 13))
printf("%s ", places[BILLIONS]);
break;
// Add cases to increase digit count supported
//case 13: //T /*- add code here -*/ break;
default: break;
}
count--; i--;
}
printf("\n\n");
}
Примеры:
$>./num_to_words.exe -1000000
$>number: -1,000,000
$>negative one million
$>./num_to_words.exe 123456789011
$>number: 123,456,789,011
$>one hundred twenty three billion four hundred fifty six million seven hundred eighty nine thousand eleven
$>./num_to_words.exe 123456789012
$>number: 123,456,789,012
$>one hundred twenty three billion four hundred fifty six million seven hundred eighty nine thousand twelve
$>./num_to_words.exe -123456789012
$>number: -123,456,789,012
$>negative one hundred twenty three billion four hundred fifty six million seven hundred eighty nine thousand twelve
$>./num_to_words.exe 0
$>number: 0
$>zero
$>./num_to_words.exe 1
$>number: 1
$>one