Ir ao conteúdo

Posts recomendados

Postado

Bom dia pessoal, preciso de ajuda para criar um algoritmo que solicite ao usuário UM valor inteiro de 8 a 9 dígitos, que irá representar o número de um CPF. A seguir, calcule os dois dígitos verificadores, , e exiba o CPF completo.

Até agora fiz isso, porém o segundo digito não da certo, o primeiro digito aparentemente está correto, PODEM ME AJUDAR, POR FAVOR?

<>

#include <iostream>

using namespace std;


 

int main ( )

{

int CPF , x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10 , x11 , D1 , D2 ;

cout<<("Digite o valor do CPF sem os digitos verificadores \n" ) ;

cin>>CPF;

x1 = CPF / 100000000 ;

x2 = (CPF / 10000000) % 10 ;

x3 = (CPF / 1000000) % 10 ;

x4 = (CPF / 100000) % 10 ;

x5 = (CPF / 10000) % 10 ;

x6 = (CPF / 1000) % 10 ;

x7 = (CPF / 100) % 10 ;

x8 = (CPF / 10) % 10 ;

x9 = CPF % 10 ;

 

D1 = (( x1 * 10 + x2 * 9 + x3 * 8 + x4 * 7 + x5 * 6 + x6 * 5 + x7 * 4 + x8 * 3 + x9 * 2 ) % 11);

 

if (D1 < 2) {

x10 = 0;

}

else if (D1 > 2) {

((x10 = 11 - D1)) ;

}

 

else

 

D2 = (( x1 * 11 + x2 * 10 + x3 * 9 + x4 * 8 + x5 * 7 + x6 * 6 + x7 * 5 + x8 * 4 + x9 * 3 + x10 * 2 ) % 11 );

 

if (D2 < 2){

x11 = 0;

}

else if (D2 > 2) {

((x11 = 11 - D2)) ;

}

cout <<CPF<<x10<<x11<<endl;

 

return 0 ;

}

Postado

eu postei isso meses atras, como parte de um exemplo. Deve dar para pesquisar aqui direto no conteúdo do forum

adicionado 0 minutos depois

Seu código parece muito complicado :( Não precisa

 

adicionado 12 minutos depois

De uma olhada nesse, que faz a conta certa

#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "string.h"


int main(int artgc, char** argv)
{
	int valor1, valor2, valor3, valor4;	// os numeros
	char d1, d2, d3; // os delimitadores
	int n;
	int soma, i;  // para calculo dos DV 123.456.789-09 OK

	printf("Entre com o CPF no formato 012.345.678-90 e Tecle ENTER ao terminar\n");
	printf("\nCPF: ");

	n = scanf( "%3d%c%3d%c%3d%c%2d", &valor1, &d1, &valor2, &d2, &valor3, &d3, &valor4 );

	// o que leu?
	printf("\nscanf() leu %d itens\n", n);

	// os valores
	printf("scanf()     valor1 = %03d\n", valor1);
	printf("scanf()     valor2 = %03d\n", valor2);
	printf("scanf()     valor3 = %03d\n", valor3);
	printf("scanf()     valor4 = %02d\n", valor4);

	// os delimitadores
	printf("scanf()     delimitador 1 = [%c]\n", d1);
	printf("scanf()     delimitador 2 = [%c]\n", d2);
	printf("scanf()     delimitador 3 = [%c]\n", d3);

	// mostra os valores afinal
	printf("\nCPF lido %03d.%03d.%03d-%02d\n", valor1, valor2, valor3, valor4);

	// aqui vão os digitos 1 a 1 para calcular os DV
	int digito[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	digito[0] =  valor1 / 100;
	digito[1] = (valor1 % 100) / 10;
	digito[2] =  valor1 % 10;

	digito[3] =  valor2 / 100;
	digito[4] = (valor2 % 100) / 10;
	digito[5] =  valor2 % 10;

	digito[6] =  valor3 / 100;
	digito[7] = (valor3 % 100) / 10;
	digito[8] =  valor3 % 10;

	digito[ 9] = valor4 / 10;
	digito[10] = valor4 % 10;


	printf("Digito a Digito: ");
	for (i = 0; i < 11; i = i + 1)
	{
		printf("%d ", digito[i]);
	}
	printf("\n");

	/////////////////////////////////////////////////////////// DV 1

	// o primeiro digito verificador, modulo 11 dos 9
	soma = 0;
	for (i = 0; i < 9; i = i + 1)
		soma = soma + digito[i] * (10-i); // 10..2

	// essa e a conta que da nome ao processo
	soma = soma % 11;
	if (soma > 1)
		digito[9] = 11 - soma;
	else
		digito[9] = 0;

	/////////////////////////////////////////////////////////// DV 2

	// o segundo DV, modulo 11 dos 10
	soma = 0;
	for (i = 0; i < 10; i = i + 1)
		soma = soma + digito[i] * (11 - i); // 11..2

	// essa e a conta que da nome ao processo
	soma = soma % 11;
	if (soma > 1)
		digito[10] = 11 - soma;
	else
		digito[10] = 0;


	printf("\nDV calculados: %d %d\n", digito[9], digito[10]);

	// compara os digitos
	int dv1ok = digito[9] == (valor4 / 10);
	int dv2ok = digito[10] == (valor4 % 10);

	if (dv1ok && dv2ok)
	{
		printf("CPF valido\n");
	}
	else
	{
		if (!dv1ok) printf("DV1 'devia ser %d. Lido %d\n", digito[9], (valor4 / 10));
		if (!dv2ok) printf("DV2 'devia ser %d. Lido %d\n", digito[10], (valor4 % 10));
		printf("CPF INVALIDO\n");
	};	// if
}	// main

Isso era um exemplo para o uso de scanf() não para calcular os DV. Então tem muitos comentários e muitos passos a mais... Mas calcula os dois DV

adicionado 32 minutos depois
int cpf_dv(const char* numero)
{
	// aqui vão os digitos 1 a 1 para calcular os DV
	int digito[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	int soma = 0;
	int i = 0;
	for (i = 0; i < 9; i += 1) digito[i] = numero[i] - '0';

	// o primeiro digito verificador, modulo 11 dos 9
	soma = 0;
	for (i = 0; i < 9; i = i + 1)
		soma = soma + digito[i] * (10 - i); // 10..2
	// essa e a conta que da nome ao processo
	soma = soma % 11;
	if (soma > 1)
		digito[9] = 11 - soma;
	else
		digito[9] = 0;

	// o segundo DV, modulo 11 dos 10
	soma = 0;
	for (i = 0; i < 10; i = i + 1)
		soma = soma + digito[i] * (11 - i); // 11..2
	// essa e a conta que da nome ao processo
	soma = soma % 11;
	if (soma > 1)
		digito[10] = 11 - soma;
	else
		digito[10] = 0;

	//printf("\nDV calculados: %d %d\n", digito[9], digito[10]);
	return digito[9] * 10 + digito[10];
};

Essa função é aquele código, sem o lance de scanf(): você passa o valor ela retorna o dígito. Nada mais.

Postado

Dê uma olhada nesse arquivo. Está escrito em Java, mas pode ser adaptado.

 

Essa classe calcula os dígitos e faz a verificação para determinar se o CPF informado é válido. No seu caso, atente-se a maneira como foram calculados os dígitos.

Postado
15 minutos atrás, AdrianoSiqueira disse:

Dê uma olhada nesse arquivo. Está escrito em Java, mas pode ser adaptado.

 

Essa classe calcula os dígitos e faz a verificação para determinar se o CPF informado é válido. No seu caso, atente-se a maneira como foram calculados os dígitos.

 

[off-topic]
 

Olá

Não seria mais útil se a classe fosse static de todo modo? Não parece ter razão para declarar uma instância da classe só para fazer sempre o mesmo cálculo. E mais de 120 linhas e 5 métodos para calcular isso talvez seja muito 🤔

Postado
16 minutos atrás, AdrianoSiqueira disse:

Está em processo de melhoria (mais lento do que eu queria). Obrigado pela sugestão

 

Ainda a título de sugestão e ligeiramente off-topic:

 

Essas linguagens são muito parecidas, C++ e java. Muito mesmo. Tanto que em muitos casos você pode recortar e colar trechos de código e só alterar alguma coisa entre java e C++. Algumas definições de classe por exemplo, métodos virtuais, classes abstratas, override, se mudam identificadores, e ainda assim fica parecido. E isso não é ruim.

Vou te mostrar um exemplo relacionado a esse caso para você considerar.

 

Imagine que você queira ter duas funções:

  • uma que você passa o CPF com 9 dígitos e ela te devolve os DV: calculaDV()
  • outra que recebe o CPF com 11 e ela calcula o dígito e verifica se certo,
    talvez respondendo com true ou false: DV_ok()

Em java

    public static int calculaDV(String numero); // recebe 9 e devolve os DV de 00 a 99
    public static boolean DV_ok(String numero); // recebe 11 e diz se os DV estão certos

Em C++

    int calculaDV(const char* numero); // recebe 9 e devolve os DV de 00 a 99
    int DV_ok(const char* numero); // recebe 11 e diz se os DV estão certos 

Pois é: até os comentários são iguais.
 

Agora veja os programas lado a lado. Sim, eu copiei de um pro outro e alterei umas linhas apenas...

 

calculaDV()
 

calcula.thumb.png.daf4aedd812d8ee4c755c2c92359f4b5.png


DV_ok()
 

dvok.thumb.png.cf9ffd085bac8a4954a5ad5becfe10e9.png


Até main() é igual para um teste bem besta. O MESMO teste:

main.thumb.png.cc4b52d84c323397c066121ac16972f5.png

E o resultado, claro. 

 

cpf-out.thumb.png.659535a007563ac7c43126055a0b9fce.png
 

:D 

 

Entendeu a razão de usar static em java? Não se usa uma instância nesse caso. Fica mais chato e menos útil. Em C++ é igualzinho. Eu escrevi em C por engano, mas compila em C++. Depois eu posto como seria em C++ mas já adianto que é igual a java ;) 

 

 

Postado
6 minutos atrás, arfneto disse:

Fica mais chato

Concordo, quando eu escrevi a classe, eu nem pensei nisso. Estava com uma pilha de outras classes para fazer, acabei me focando apenas na funcionalidade e me esqueci da usabilidade. Agora tenho que voltar e mexer com essa classe de novo 🙄. E tudo porque eu não fiz os devidos testes antes....

Postado
1 minuto atrás, AdrianoSiqueira disse:

Concordo, quando eu escrevi a classe, eu nem pensei nisso. Estava com uma pilha de outras classes para fazer, acabei me focando apenas na funcionalidade e me esqueci da usabilidade. Agora tenho que voltar e mexer com essa classe de novo 🙄. E tudo porque eu não fiz os devidos testes antes....

 

Se está funcionando está bem. Mas você tem que declarar algo dessa classe para poder usar, e não é isso que você quer, já que o que procura é só usar os dois métodos da classe, que não dependem de nada da classe em si. Ela não tem estado, digamos. É só uma biblioteca de funções.

 

Em C++ (como eu disse, tinha me esquecido que o tópico era C++) bastaria algo assim

struct libCPF
{
	static int calculaDV(const char* numero);
	static bool DV_ok(const char* numero);
};

e main() em C++ ficaria


int main(int argc, char** argv)
{
	const char* numero = "111222333";
	int n = libCPF::calculaDV(numero);
	printf("DV calculados para '%s'= %d\n", numero, n);
	// agora poe o DV e testa com a outra rotina
	char numero_com_dv[12];
	memcpy(numero_com_dv, numero, 9);
	numero_com_dv[9] = n / 10 + '0';
	numero_com_dv[10] = n % 10 + '0';
	numero_com_dv[11] = 0;
	printf("numero com DV: '%s'\n",
		numero_com_dv);
	if (libCPF::DV_ok(numero_com_dv))
		printf("DV ok para '%s'\n",
			numero_com_dv);
	else
		printf("Erro com o DV calculado para '%s'\n",
			numero_com_dv);
};	// main

Sim, bastou acrescentar o prefixo da classe libCPF:: em C++ em relação ao programa em C :D como vê acima

 

Eis o programa todo em C++

#include <iostream>
using namespace std;

struct libCPF
{
	static int calculaDV(const char* numero);
	static bool DV_ok(const char* numero);
};

int main(int argc, char** argv)
{
	const char* numero = "111222333";
	int n = libCPF::calculaDV(numero);
	printf("DV calculados para '%s'= %d\n", numero, n);
	// agora poe o DV e testa com a outra rotina
	char numero_com_dv[12];
	memcpy(numero_com_dv, numero, 9);
	numero_com_dv[9] = n / 10 + '0';
	numero_com_dv[10] = n % 10 + '0';
	numero_com_dv[11] = 0;
	printf("numero com DV: '%s'\n",
		numero_com_dv);
	if (libCPF::DV_ok(numero_com_dv))
		printf("DV ok para '%s'\n",
			numero_com_dv);
	else
		printf("Erro com o DV calculado para '%s'\n",
			numero_com_dv);
};	// main

int libCPF::calculaDV(const char* numero)
{
	// aqui vão os digitos 1 a 1 para calcular os DV
	int digito[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	int soma = 0;
	int i = 0;
	for (i = 0; i < 9; i += 1) digito[i] = numero[i] - '0';

	// o primeiro digito verificador, modulo 11 dos 9
	soma = 0;
	for (i = 0; i < 9; i = i + 1)
		soma = soma + digito[i] * (10 - i); // 10..2
	// essa e a conta que da nome ao processo
	soma = soma % 11;
	if (soma > 1)
		digito[9] = 11 - soma;
	else
		digito[9] = 0;

	// o segundo DV, modulo 11 dos 10
	soma = 0;
	for (i = 0; i < 10; i = i + 1)
		soma = soma + digito[i] * (11 - i); // 11..2
	// essa e a conta que da nome ao processo
	soma = soma % 11;
	if (soma > 1)
		digito[10] = 11 - soma;
	else
		digito[10] = 0;

	//printf("\nDV calculados: %d %d\n", digito[9], digito[10]);
	return digito[9] * 10 + digito[10];
};	// libCPF::calculaDV()

bool libCPF::DV_ok(const char* numero)
{
	if (strlen(numero) < 11) return 0;
	char cpf[10];
	memcpy(cpf, numero, 9);
	cpf[9] = 0;
	int dv = (numero[9] - '0') * 10
		+ numero[10] - '0';
	int calculado = calculaDV(cpf);
	return (dv == calculado);
};  // libCPF::DV_ok()

 

Claro, há muitas maneiras de fazer isso e essa pode nem ser muito boa em C, C++ ou java ... Mas calcula os DV e mostra a mecânica da coisa.
 

 

 

  • Obrigado 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!