Escrever um programa em C que leia um valor inteiro (limite na casa do milhar), e o imprima em forma de caracteres, ou seja, por extenso. Ex. : 98 = noventa e oito.

Passo 1

O que o problema pede e o que temos de entrada/saída.
  • Pede-se um programa em C que leia um valor inteiro e o imprima por extenso (em português).
  • O enunciado diz que o limite é “na casa do milhar”, ou seja vamos considerar números entre 0 e 9999 (inclusive).
  • Entrada: um inteiro n.
  • Saída: uma linha com o número por extenso (por exemplo, para 98 imprimir “noventa e oito”).
Informações relevantes dadas:
  • Exemplos de formato: 98 \to “noventa e oito”.
  • Devemos tratar especiais como números entre 10 e 19, o caso de 100 (“cem”), e o caso de 1000 (“mil”).

Passo 2

Estratégia geral (quebra do número em partes): como vamos pensar no problema.
  • Vamos decompor o número n em milhares, centenas, dezenas e unidades usando divisão inteira e módulo: \text{milhares} = \left\lfloor \dfrac{n}{1000} \right\rfloor
\text{resto} = n \bmod 1000
\text{centenas} = \left\lfloor \dfrac{\text{resto}}{100} \right\rfloor
\text{resto2} = \text{resto} \bmod 100
\text{dezenas} = \left\lfloor \dfrac{\text{resto2}}{10} \right\rfloor
\text{unidades} = \text{resto2} \bmod 10
  • Com esses dígitos conseguimos montar o texto por extenso combinando palavras para milhares, centenas, dezenas e unidades.
  • Observações importantes (casos especiais):
    • 0 deve virar “zero”.
    • De 10 a 19 são formas próprias (dez, onze, doze, …).
    • 100 é “cem” quando sozinho; se for 101 usa-se “cento e um”.
    • Para 1000 usamos “mil” (não “um mil”). Para 2000 usamos “dois mil”, etc.
  • Para montar a frase em português precisaremos juntar as partes com o conectivo " e " entre as partes não vazias. Para simplificar e garantir saídas compreensíveis, adotaremos a regra prática: juntar todas as partes não vazias (milhares, centenas, dezenas, unidades ou bloco 10–19) em ordem, separando-as por " e ". Essa regra produz saídas corretas e legíveis para os valores no intervalo pedido.

Passo 3

Como representamos as palavras: vetores de strings.
  • Vamos criar vetores de strings para:
    • unidades: 0 9 (a posição 0 ficará vazia ou “zero” tratada à parte)
    • especiais de 10…19 (dez, onze, doze, …)
    • dezenas (vinte, trinta, …, noventa)
    • centenas (cento, duzentos, …, novecentos) — reparando que 100 sozinho é “cem”
  • Exemplo (em pseudocódigo/ideia):
    • units[1] = “um”, units[2] = “dois”, …
    • teens[0] = “dez”, teens[1] = “onze”, … (teens[units])
    • tens[2] = “vinte”, tens[3] = “trinta”, …
    • hundreds[1] = “cento”, hundreds[2] = “duzentos”, … (tratando “cem” quando necessário)

Passo 4

Regras detalhadas de montagem por blocos (implementação lógica).
  • Se n = 0 escrevemos “zero” e fim.
  • Extrair milhares, centenas, dezenas e unidades como na Passo 2.
  • Montagem por blocos (em ordem):
    1. Milhares:
      • se milhares = 0 nada.
      • se milhares = 1 adiciona “mil”.
      • se milhares > 1 adiciona “<unidade> mil” (ex.: “dois mil”).
    2. Centenas:
      • se centenas = 0 nada.
      • se centenas = 1 e dezenas = 0 e unidades = 0 então “cem”.
      • caso contrário usar hundreds[centenas] (onde 1 -> “cento”).
    3. Dezenas e unidades:
      • se dezenas = 1 usar teens[unidades] e pular unidade.
      • se dezenas \ge 2 usar tens[dezenas]; se unidade > 0 acrescentar unidade separada (cada parte será depois conectada por " e ").
      • se dezenas = 0 e unidades > 0 usar unidade.
  • Para simplificar as regras de onde colocar " e ", colocamos em um vetor/array cada pedaço textual não-vazio (ex.: “mil”, “cento”, “vinte”, “três”) e depois concatenamos essas partes com " e " entre elas. Isso garante que números como 98 resultem em “noventa e oito”; 100 em “cem”; 101 em “cento e um”; 1000 em “mil”, e 1001 em “mil e um”.

Passo 5

Estruturas C que vamos usar e porquê (aula rápida).
  • Vetor de const char * para guardar as palavras (strings literais). Ex.: const char *units[] = {"", “um”, “dois”, …};
  • Manipulação de strings: usaremos um buffer resultado (char out[200]) e funções como strcpy/strcat/sprintf para montar as partes.
  • Divisão inteira e resto: em C usamos operador /) para divisão inteira e \% para resto. Ex.: milhares = n / 1000; resto = n \% 1000;
  • Leitura: usar scanf("%d",&n) para ler o inteiro.
  • Função auxiliar: criar uma função que recebe n e escreve no buffer o texto por extenso, separando responsabilidade e deixando o main limpo.

Passo 6

Código completo (explicado passo a passo dentro dele).
  • Abaixo segue o programa em C que implementa todo o raciocínio anterior.
  • O programa lê um inteiro, verifica intervalo 0..9999 e imprime o por extenso usando a função auxiliar.
#include <stdio.h>
#include <string.h>

void numero_por_extenso(int n, char *out) {
    if (n == 0) { strcpy(out, "zero"); return; }
    if (n < 0 || n > 9999) { strcpy(out, "numero fora do intervalo"); return; }

    const char *units[] = {"", "um", "dois", "tres", "quatro", "cinco", "seis", "sete", "oito", "nove"};
    const char *teens[] = {"dez", "onze", "doze", "treze", "quatorze", "quinze", "dezesseis", "dezessete", "dezoito", "dezenove"};
    const char *tens[] = {"", "", "vinte", "trinta", "quarenta", "cinquenta", "sessenta", "setenta", "oitenta", "noventa"};
    const char *hundreds[] = {"", "cento", "duzentos", "trezentos", "quatrocentos", "quinhentos", "seiscentos", "setecentos", "oitocentos", "novecentos"};

    int milhares = n / 1000;
    int resto = n % 1000;
    int centenas = resto / 100;
    resto = resto % 100;
    int dezenas = resto / 10;
    int unidades = resto % 10;

    char parts[10][50];
    int pcount = 0;

    /* Milhares */
    if (milhares) {
        if (milhares == 1) {
            strcpy(parts[pcount++], "mil");
        } else {
            sprintf(parts[pcount++], "%s mil", units[milhares]);
        }
    }

    /* Centenas */
    if (centenas) {
        if (centenas == 1 && dezenas == 0 && unidades == 0) {
            strcpy(parts[pcount++], "cem"); /* caso exato 100, 1000 já tratado */
        } else {
            strcpy(parts[pcount++], hundreds[centenas]);
        }
    }

    /* Dezenas e unidades */
    if (dezenas == 1) {
        strcpy(parts[pcount++], teens[unidades]);
    } else {
        if (dezenas >= 2) {
            strcpy(parts[pcount++], tens[dezenas]);
        }
        if (unidades > 0) {
            strcpy(parts[pcount++], units[unidades]);
        }
    }

    /* Concatena todas as partes com " e " */
    out[0] = '\0';
    for (int i = 0; i < pcount; ++i) {
        if (i) strcat(out, " e ");
        strcat(out, parts[i]);
    }
}

int main(void) {
    int n;
    if (scanf("%d", &n) != 1) return 0;
    char res[200];
    numero_por_extenso(n, res);
    printf("%s\n", res);
    return 0;
}

Passo 7

Explicando rapidamente como o código funciona na prática (passo a passo no exemplo 98).
  • Leitura: suponha que o usuário digite 98.
  • Decomposição:
    • milhares = 98 / 1000 = 0
    • resto = 98
    • centenas = 98 / 100 = 0
    • resto2 = 98
    • dezenas = 98 / 10 = 9
    • unidades = 98 \% 10 = 8
  • Montagem:
    • partes não vazias serão: tens[9] = “noventa”, units[8] = “oito”.
    • junta-se com " e " -> “noventa e oito”.
  • Impressão: o programa imprime exatamente “noventa e oito”.

Passo 8

Outros exemplos e confirmações rápidas para treinar na prova.
  • 0 \to “zero”.
  • 100 \to “cem”.
  • 101 \to “cento e um”.
  • 512 \to “quinhentos e doze”.
  • 1000 \to “mil”.
  • 2001 \to “dois mil e um”.
  • 9999 \to “nove mil e novecentos e noventa e nove”.

Passo 9

Dicas finais para você na prova (motivação e cuidados).
  • Separe o problema: decompor e depois montar é a chave. Se conseguir dividir corretamente, a montagem vira um trabalho de tabelas.
  • Faça arrays de strings prontos na mão antes de codificar; isso evita traduções erradas.
  • Teste alguns casos-limite: 0, 100, 101, 1000, 9999.
  • Confie no passo-a-passo: para números maiores a lógica é a mesma, só precisa ampliar as tabelas (se pedirem milhões, bilhões, etc).
  • Você consegue! Respire, foque nas etapas (decompor → mapear → concatenar) e vai dar certo na prova.

Resposta

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

void numero_por_extenso(int n, char *out) {
    if (n == 0) { strcpy(out, "zero"); return; }
    if (n < 0 || n > 9999) { strcpy(out, "numero fora do intervalo"); return; }

    const char *units[] = {"", "um", "dois", "tres", "quatro", "cinco", "seis", "sete", "oito", "nove"};
    const char *teens[] = {"dez", "onze", "doze", "treze", "quatorze", "quinze", "dezesseis", "dezessete", "dezoito", "dezenove"};
    const char *tens[] = {"", "", "vinte", "trinta", "quarenta", "cinquenta", "sessenta", "setenta", "oitenta", "noventa"};
    const char *hundreds[] = {"", "cento", "duzentos", "trezentos", "quatrocentos", "quinhentos", "seiscentos", "setecentos", "oitocentos", "novecentos"};

    int milhares = n / 1000;
    int resto = n % 1000;
    int centenas = resto / 100;
    resto = resto % 100;
    int dezenas = resto / 10;
    int unidades = resto % 10;

    char parts[10][50];
    int pcount = 0;

    if (milhares) {
        if (milhares == 1) {
            strcpy(parts[pcount++], "mil");
        } else {
            sprintf(parts[pcount++], "%s mil", units[milhares]);
        }
    }

    if (centenas) {
        if (centenas == 1 && dezenas == 0 && unidades == 0) {
            strcpy(parts[pcount++], "cem");
        } else {
            strcpy(parts[pcount++], hundreds[centenas]);
        }
    }

    if (dezenas == 1) {
        strcpy(parts[pcount++], teens[unidades]);
    } else {
        if (dezenas >= 2) {
            strcpy(parts[pcount++], tens[dezenas]);
        }
        if (unidades > 0) {
            strcpy(parts[pcount++], units[unidades]);
        }
    }

    out[0] = '\0';
    for (int i = 0; i < pcount; ++i) {
        if (i) strcat(out, " e ");
        strcat(out, parts[i]);
    }
}

int main(void) {
    int n;
    if (scanf("%d", &n) != 1) return 0;
    char res[200];
    numero_por_extenso(n, res);
    printf("%s\n", res);
    return 0;
}

Exercícios relacionados