Convert numbers to words

A

Abhishek Jha

How can we write a shortest program in c to convert given number to
words format. example input 5012 Output: five thousand tewlve.
 
J

Jack Klein

How can we write a shortest program in c to convert given number to
words format. example input 5012 Output: five thousand tewlve.

You can use any general purpose editor that can save files as plain
text.
 
D

Derrick Coetzee

Abhishek said:
How can we write a shortest program in c to convert given number to
words format. example input 5012 Output: five thousand tewlve.

If I interpret you literally, the shortest possible C program on a
platform with 32-bit integers would probably use the number to seek into
a 100GB file and read the string out. I imagine this is rather
unfeasible for a homework assignment.
 
B

Ben Pfaff

How can we write a shortest program in c to convert given number to
words format. example input 5012 Output: five thousand tewlve.

I've posted this here several times before. I have a version for
Japanese too if you want that.

#include <stdio.h>
#include <stdlib.h>

char *ordinal (char buf[1024], int value);

int
main (int argc, char *argv[])
{
char buf[1024];

if (argc != 2)
{
printf ("usage: ordinal <number>\n");
return EXIT_FAILURE;
}

ordinal (buf, atoi (argv[1]));
puts (buf);
return EXIT_SUCCESS;
}

/* Works for positive and negative numbers up to 9 digits long,
if you speak American English. */
char *
ordinal (char buf[1024], int value)
{
static const char *const powers[]
= {"thousand", "million", "billion"};

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

static const char *const tens[]
= {"twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety"};

char *cp = buf;

if (value < 0)
{
cp += sprintf (cp, "negative ");
value = -value;
}
else if (value == 0)
{
strcpy (buf, "zero");
return buf;
}

{
int part_stack[4];
int *part_ptr = part_stack;

for (; value; value /= 1000)
*part_ptr++ = value % 1000;

while (part_ptr > part_stack)
{
int p = *--part_ptr;

if (p >= 100)
{
cp += sprintf (cp, "%s hundred ", ones[p / 100 - 1]);
p %= 100;
}

if (p >= 20)
{
if (p % 10)
cp += sprintf (cp, "%s-%s ", tens[p / 10 - 2], ones[p % 10 - 1]);
else
cp += sprintf (cp, "%s ", tens[p / 10 - 2]);
}
else if (p > 0)
cp += sprintf (cp, "%s ", ones[p - 1]);

if (p && part_ptr > part_stack)
cp += sprintf (cp, "%s ", powers[part_ptr - part_stack - 1]);
}
}

cp[-1] = 0;
return buf;
}

/*
Local variables:
compile-command: "gcc -W -Wall -ansi -pedantic ordinal.c -o ordinal"
End:
*/
 
P

Peter Nilsson

Ben said:
ordinal (buf, atoi (argv[1]));
...
/* Works for positive and negative numbers up to 9 digits long,
if you speak American English. */
char *
ordinal (char buf[1024], int value)

You assume an int can store a 9 digit integer. I think you should
change the parameter to long, and (also) use strtol instead of atoi.
 
B

Ben Pfaff

Peter Nilsson said:
Ben said:
ordinal (buf, atoi (argv[1]));
...
/* Works for positive and negative numbers up to 9 digits long,
if you speak American English. */
char *
ordinal (char buf[1024], int value)

You assume an int can store a 9 digit integer. I think you should
change the parameter to long, and (also) use strtol instead of atoi.

If you supply a 9 digit integer to it, assuming that it is
possible, it will convert it. That's all I was intending to
state.
 
M

myhotline

I've posted this here several times before. I have a version for
Japanese too if you want that.
:)..i like that...will that Japanese version compile on ANSI C
compiler...-:)

Cheers
Waqas
 
B

Ben Pfaff

:)..i like that...will that Japanese version compile on ANSI C
compiler...-:)

It writes its output as romanized text, so it should compile and
run everywhere (modulo any bugs).

Here it is:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *ordinal (char buf[1024], unsigned value);

int
main (int argc, char *argv[])
{
char buf[1024];

if (argc != 2)
{
printf ("usage: ordinal <number>\n");
return EXIT_FAILURE;
}

ordinal (buf, atoi (argv[1]));
puts (buf);
return EXIT_SUCCESS;
}

char *
ordinal (char buf[1024], unsigned value)
{
static const char *const powers[]
= {"man", "oku"};

static const char *const values[][9] =
{
{"sen", 0, "sanzen", 0, 0, 0, 0, "hassen", 0},
{"hyaku", 0, "sanbyaku", 0, 0, "roppyaku", 0, "happyaku", 0},
{"juu", 0, 0, 0, 0, 0, 0, 0, 0},
{"ichi", "ni", "san", "yon", "go", "roku", "nana", "hachi", "kyuu"},
};

static const char *const *const ones = values[3];

char *cp = buf;

if (value == 0)
{
strcpy (buf, "rei");
return buf;
}

{
int part_stack[4];
int *part_ptr = part_stack;

for (; value; value /= 10000)
*part_ptr++ = value % 10000;

while (part_ptr > part_stack)
{
int index[4];
int p, i;

p = *--part_ptr;
for (i = 3; i >= 0; i--)
{
index = p % 10;
p /= 10;
}

for (i = 0; i < 4; i++)
{
int c = index;
if (c != 0)
{
if (values[c - 1] == 0)
cp += sprintf (cp, "%s%s ", ones[c - 1], values[0]);
else
cp += sprintf (cp, "%s ", values[c - 1]);
}
}

if (*part_ptr && part_ptr > part_stack)
cp += sprintf (cp, "%s ", powers[part_ptr - part_stack - 1]);
}
}

cp[-1] = 0;
return buf;
}

/*
Local variables:
compile-command: "gcc -W -Wall -ansi -pedantic ordinal-jp.c -o ordinal-jp"
End:
*/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top