#include <stdio.h>
#include <string.h>

#define MAXRES_S		350
#define MAXTERN_S		40
#define MAXPOW			5

typedef struct
{
	unsigned int n;
	char *w;
} node;

char *ext999 (unsigned int n)
{
	unsigned int i, x, y;
	char *buf;
	node rel[] =
	{
		{900,	"novecentos"},	{800,	"oitocentos"},
		{700,	"setecentos"},	{600,	"seissentos"},
		{500,	"quinhentos"},	{400,	"quatrocentos"},
		{300,	"trezentos"},	{200,	"duzentos"},
		{100,	"cento"},	{90,	"noventa"},
		{80,	"oitenta"},	{70,	"setenta"},
		{60,	"sessenta"},	{50,	"cinqüenta"},
		{40,	"quarenta"},	{30,	"trinta"},
		{20,	"vinte"},	{19,	"dezenove"},
		{18,	"dezoito"},	{17,	"dezessete"},
		{16,	"dezesseis"},	{15,	"quinze"},
		{14,	"quatorze"},	{13,	"treze"},
		{12,	"doze"},	{11,	"onze"},
		{10,	"dez"},		{9,	"nove"},
		{8,	"oito"},	{7,	"sete"},
		{6,	"seis"},	{5,	"cinco"},
		{4,	"quatro"},	{3,	"três"},
		{2,	"dois"},	{1,	"um"},
	};

	buf = (char *) malloc(MAXTERN_S);
	buf[0] = '\0';

	if (!n)
	{
		strcpy(buf, "zero");
		return buf;
	} else if (n == 100) {
		strcpy(buf, "cem");
		return buf;
	}

	while (n)
	{
		for (i = 0; i < sizeof(rel); i++)
		{
			x = rel[i].n;
			y = n % x;
			if (x + y == n)
			{
				n = y;
				strcat(buf, rel[i].w);
				if (n)
					strcat(buf, " e ");
				break;
			}
		}
	}

	return buf;
}

char *extenso (long n)
{
	unsigned long x;
	unsigned int y;

	int i, j, k;
	char *res, *p;
	unsigned int tern[MAXPOW];

	char *ord[] =
	{
		NULL,		NULL,
		"mil",		"mil",
		"milhão",  	"milhões",
		"bilhão",	"bilhões",
/*
		// total e absolutamente desnecessário para máquinas de 32 bits
		"trilhão",	"trilhões",
		"quadrilhão",	"quadrilhões",
*/
	};

	res = (char *) malloc(MAXRES_S);
	res[0] = '\0';

	if (n < 0)
	{
		n *= -1;
		strcat(res, "menos ");
	}

	if (n < 1000)
	{
		strcat(res, ext999(n));
	} else {
		x = n;
		for (j = 0; x; j++)
		{
			y = x % 1000;
			x /= 1000;

			tern[j] = y;
		}

		for (i = j - 1; i >= 0; i--)
		{
			if (y = tern[i])
			{
				p = ext999(y);
				strcat(res, p);
				free(p);

				k = i * 2;
				if (y != 1)
					k++;

				if (p = ord[k])
				{
					strcat(res, " ");
					strcat(res, p);
				}

				strcat(res, " e ");
			}
		}
		res[strlen(res) - 3] = '\0';
	}

	return res;
}


int main (void) {
	long n;
	char *p;

	do
	{
		printf("digite um número (0 para sair): ");
		scanf("%ld", &n);
		fflush(stdin);

		p = extenso(n);
		printf("você digitou \"%s\"\n\n", p);
		free(p);
	} while (n);

	return 0;
}

