Um CPF (Cadastro de Pessoa Física) é composto de 11 números (
), sendo que os dois últimos números (
e
) são dígitos verificadores, isto é, é realizado um conjunto de operações com os números de
a
para se obter os número
e
. Este procedimento evita que um CPF seja digitado errado, pois toda vez que alguém o insere em um sistema/programa, os números de verificação são calculados e é feita a verificação dos valores calculados com os valores
e
digitados. Se pelo menos um dos números for digitado errado, o cálculo de
e
não serão iguais aos valores digitados, então o CPF pode ser considerado inválido.
Segue o procedimento para o cálculo de
e
e um caso particular de número de CPF inválido.
Cálculo de
:
resto da divisão inteira de
por 11
Se
então
; caso contrário
Cálculo de
:
resto da divisão inteira de
por 11
Se
então
; caso contrário
Caso particular:
Se todos os números do CPF forem iguais (exemplos: 555.555.555, 222.222.222, etc.), o CPF não é válido.
Desenvolva um programa no qual o usuário entra com os nove primeiros números do CPF e o programa retorne os dois números de verificação de CPF, conforme o algoritmo apresentado. O usuário deverá digitar os números de três em três separado-os por ponto. Utilize apenas um comando scanf para realizar a leitura do número do CPF.
Dica: utilize a máscara de leitura “%1d%1d%1d.%1d%1d%1d.%1d%1d%1d”.
Segue o procedimento para o cálculo de
Se
Se
Dica: utilize a máscara de leitura “%1d%1d%1d.%1d%1d%1d.%1d%1d%1d”.
Passo 1
O enunciado pede que eu desenvolva um programa que:
- Receba do usuário os nove primeiros dígitos de um CPF, digitados em grupos de três separados por ponto (formato exemplo:
123.456.789). - Calcule os dois dígitos verificadores
e seguindo o algoritmo fornecido. - Use apenas um único comando
scanfpara ler os nove dígitos (a dica é usar a máscara"%1d%1d%1d.%1d%1d%1d.%1d%1d%1d"). - Considere o caso particular: se todos os nove dígitos forem iguais (ex.:
555.555.555) o CPF é inválido.
Informações essenciais dadas:
- Fórmula para
:
- Resto
é o resto da divisão inteira de por 11. Se então ; caso contrário . - Fórmula para
:
- Resto
é o resto da divisão inteira de por 11. Se então ; caso contrário . - Caso particular: se todos os dígitos
a forem iguais, o CPF é inválido.
A partir daqui vou explicar passo a passo como implementar e como entender cada operação (sem pular etapas).
Passo 2
Entendendo os conceitos matemáticos usados (bem devagar e com calma):
- O que é o “resto da divisão inteira por 11”? É a operação matemática que chamamos de “módulo 11”. Para dois inteiros
e positivos, o resto de dividido por é o número tal que existe um inteiro com e . Em C isso é feito com o operador %:r = a % b. - Por que multiplicar por pesos (10, 9, 8, …)? É o mecanismo de verificação: cada posição tem um peso diferente para dar mais sensibilidade a erros de transposição/erro de dígito. Não precisamos provar que é bom — apenas aplicar o algoritmo.
- Como interpretar as condições
r<2? São regras específicas do CPF: se o resto é 0 ou 1, o dígito verificador vira 0; caso contrário subtrai-se o resto de 11.
Vou mostrar exatamente como calcular cada parte e como isso vira código.
Passo 3
Algoritmo passo a passo (manual, para entender antes do código):
- Leitura: ler os nove dígitos
a com um único scanfusando a máscara"%1d%1d%1d.%1d%1d%1d.%1d%1d%1d". Cada\%1dlê um dígito (um número de 0 a 9) e os pontos na máscara consomem os pontos digitados pelo usuário. Ex.: entrada111.444.777preencherá os nove inteiros. - Calcular
somando cada dígito pelo seu peso:
(Observe que quando
o peso é
porque
; quando
o peso é
porque
.)
3) Calcular . Em C:
4) Determinar :
3) Calcular
r1 = v1 % 11;.4) Determinar
- Se
então . - Senão
.
- Calcular
somando os nove primeiros dígitos com pesos deslocados (começando em 11) e incluindo com peso 2:
(Quando
o peso é 11 porque
; quando
o peso é 3 porque
.)
6) Calcular .
7) Determinar :
6) Calcular
7) Determinar
- Se
então . - Senão
.
- Caso particular: verificar se todos os
a são iguais. Em código fazemos: todos_iguais = (n1==n2 && n2==n3 && ... && n8==n9). Setodos_iguaisfor verdadeiro, o CPF é inválido e devemos avisar isso em vez de apenas mostrar os dígitos verificadores.
Exemplo concreto (para fixar) com os dígitos:
111.444.777 (use isto na prova para checar passos):- Os nove dígitos são
. - Calcular
:
- Resto
. Como , . - Calcular
:
- Resto
. Como , . - Resultado: dígitos verificadores são
e , ou seja -51. - Verificação do caso particular: os dígitos não são todos iguais, então é um CPF válido nesse sentido.
Passo 4
Dicas de implementação e cuidados práticos:
- Use um array
int d[9];para guardar os nove dígitos lidos. Isso facilita loops. - Use apenas um
scanfcom a máscara:scanf("%1d%1d%1d.%1d%1d%1d.%1d%1d%1d", &d[0], &d[1], ..., &d[8]); - Para somas ponderadas (peso multiplicador), use um loop que calcula o peso a partir do índice: para
o peso do índice i(0-based) é10 - i; paraé 11 - i. - Sempre usar inteiros (
int) para somas e restos; os números envolvidos são bem pequenos (não há overflow). - Depois de calcular
e , verifique se todos os dígitos lidos eram iguais: se sim, imprima mensagem de CPF inválido; se não, imprima os dois dígitos verificadores. - Formatação da saída: o enunciado pede que o programa retorne os dois números de verificação. Podemos imprimir numa linha os dois dígitos separados (ex.:
5 1) ou juntos (51). Vou fornecer um código que imprime os dois dígitos lado a lado com hífen, mostrando também a mensagem de CPF inválido quando for o caso.
Resposta
#include <stdio.h>
int main(void) {
int d[9];
/* leitura dos nove dígitos com um único scanf usando a máscara sugerida */
if (scanf("%1d%1d%1d.%1d%1d%1d.%1d%1d%1d",
&d[0], &d[1], &d[2], &d[3], &d[4], &d[5], &d[6], &d[7], &d[8]) != 9) {
printf("Erro na leitura\n");
return 1;
}
/* verifica se todos os nove dígitos são iguais (caso particular inválido) */
int todos_iguais = 1;
for (int i = 1; i < 9; ++i) {
if (d[i] != d[0]) { todos_iguais = 0; break; }
}
if (todos_iguais) {
printf("CPF invalido\n");
return 0;
}
/* cálculo de v1 e n10 */
int v1 = 0;
for (int i = 0; i < 9; ++i) {
int peso = 10 - i; /* pesos: 10,9,8,...,2 */
v1 += d[i] * peso;
}
int r1 = v1 % 11;
int n10 = (r1 < 2) ? 0 : 11 - r1;
/* cálculo de v2 e n11 */
int v2 = 0;
for (int i = 0; i < 9; ++i) {
int peso = 11 - i; /* pesos: 11,10,9,...,3 */
v2 += d[i] * peso;
}
v2 += n10 * 2; /* peso 2 para n10 */
int r2 = v2 % 11;
int n11 = (r2 < 2) ? 0 : 11 - r2;
/* saída: os dois dígitos verificadores */
printf("%d%d\n", n10, n11);
return 0;
}