Validação de CNPJ com C

15 views
Skip to first unread message

o bilíngue

unread,
Oct 5, 2025, 10:51:48 AM (3 days ago) Oct 5
to ccppbrasil
Estou enfrentando um erro na lógica que eu elaborei para validar um CNPJ, eu fiz uma função cuja a responsabilidade é retirar os . , / e - do CNPJ, e garantir que haverá somente os 14 dígitos necessários para validação. Porém eu percebi que quando eu digito um CNPJ com os 14 dígitos válidos como 11.222.333/0001-81, mas eu coloco mais alguns números que invalidam o mesmo 11.222.333/0001-81565, o meu programa ainda dá esse CNPJ como válido.
Já tentei mudar a lógica da coisa várias vezes, mas no final eu ainda não consegui encontrar o que diabos estou fazendo de errado. Vou deixar o código abaixo e caso alguém consiga ver algo que eu não estou vendo eu ficaria muito grato de me mostrar o que eu estou fazendo de errado. Abaixo segue o código com todas as funções que eu estou usando para validação do CNPJ.

// vou adicionar a lógica de validação de um CNPJ
#include <stdio.h>
#include "CNPJ.h"
#include<ctype.h>

// essa função vai receber os caracteres do cnpj e retirar os . e / do valor, 11.222.333/0001-81 = 11222333000181
// e depois vai converter e guardar cada char de 1 1 2 2 2 3 3 3 0 0 0 1 8 1 para um int, para assim a função de validar_CNPJ poder somente validar
int converter_para_inteiros(CNPJ cnpj_struct, int *caracteres_convertidos){

//vamos receber os digitos do cnpj, retirar pontos e barra.
char *caracteres_iniciais = cnpj_struct.numeros;

char caracteres_finais[15];

int j = 0;

for (int i = 0; caracteres_iniciais[i] != '\0'; i++) {
if (isdigit(caracteres_iniciais[i])) {
caracteres_finais[j++] = caracteres_iniciais[i];
}

if(j == 14){
return 0;
}

}

caracteres_finais[j] = '\0'; // Adiciona o terminador nulo garantindo que é uma string válida
int tsts = sizeof(caracteres_finais) / sizeof(caracteres_finais[0]);

if (j != 14) {
// garantindo que o CNPJ vai ter os 14 dígitos.
return 0;
}

// convertendo cada digito char para o inteiro
for (int i = 0; caracteres_finais[i] != '\0'; i++){
// No c os caracteres (char) são armazenados como seus códigos númericos da tabela ASCCI, o '0' na tabela ASCII tem um valor 48, se subtrair por exemplo o dígito '9' (em char) que na tabela ASCII tem valor 57 por '0' é o mesmo que fazer 57 - 48, que resulta em 9 do tipo int. Possibilitando a conversão dos digitos CHAR em digitos INT.

caracteres_convertidos[i] = caracteres_finais[i] - '0';
// Agora o array caracteres_convertidos tem os 14 dígitos convertidos.
}

return 1;

}

int validar_CNPJ(CNPJ cnpj_struct){

int digitos[14], i, soma = 0, resto, digito_calculado;

if (converter_para_inteiros(cnpj_struct, digitos) == 0) {
// Se a conversão falhar (retorna 0), a validação para imediatamente.
return 0;
}
// os 12 numeros que precisamos para multiplicar os 12 primeiros digitos do CNPJ. Precisamos para conseguirmos o primeiro digitos dos dois ultimos
int numeros_primeiro_digito[12] = {5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
//mesma lógica usada para conseguir o primeiro dígito, a diferença é que para conseguir o segundo digito precisamos dos 13 números que estão no array.
int numeros_segundo_digito[13] = {6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
// O loop deve ir de 0 a 12 (pois temos 12 números no array numeros_primeiro_digito)
for(i = 0; i < 12; i++){

// Baseado na fórmula usada para validar o cnpj precisamos acumular a soma do produto (digito do cnpj * números da fórmula)
soma += digitos[i] * numeros_primeiro_digito[i];
}
// Ainda usando a fórmula precisamos encontrar o resto da divisão da soma por 11
resto = soma % 11;
// Para validar o digito vamos usar a condição. Se resto < 2, então D1 = 0, senão D1 = 11 - resto)
digito_calculado = (resto < 2) ? 0 : (11 - resto);
// Por ultimo comparar o décimo terceiro digito gerado na fórmula com o digito digitado pelo usuário.
if (digito_calculado != digitos[12]) {
return 0;
}
// vamos zerar a soma para efetuar a mesma lógica necessária para gerar o ultimo digito
soma = 0;

for(i = 0; i < 13; i++){
soma += digitos[i] * numeros_segundo_digito[i];
}
resto = soma % 11;

digito_calculado = (resto < 2) ? 0 : (11 - resto);

if (digito_calculado != digitos[13]) {
return 0;
}

return 1;
}



Roberto Spadim

unread,
Oct 5, 2025, 11:17:57 AM (2 days ago) Oct 5
to ccppb...@googlegroups.com

--
http://ccppbrasil.github.io/
https://twitter.com/ccppbrasil
 
[&] C & C++ Brasil - http://www.ccppbrasil.org/
Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
---
Você recebeu essa mensagem porque está inscrito no grupo "ccppbrasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para ccppbrasil+...@googlegroups.com.
Para ver esta conversa, acesse https://groups.google.com/d/msgid/ccppbrasil/98e0cebd-a2e6-48bd-9ab6-67a26cebba67n%40googlegroups.com.


--
Roberto Spadim
SPAEmpresarial

DQ

unread,
Oct 6, 2025, 8:13:52 AM (yesterday) Oct 6
to ccppbrasil
Meus poderes psíquicos (vide https://devblogs.microsoft.com/oldnewthing/20101229-00/?p=11883) sugerem que o problema está na definição da estrutura CNPJ e/ou no preenchimento do campo 'numeros'. Cabem neles todos os caracteres que você quer colocar:

DQ

Augusto Rodrigues

unread,
Oct 6, 2025, 1:46:05 PM (yesterday) Oct 6
to ccppb...@googlegroups.com
"Meus poderes psíquicos" ... rachei de rir aqui no trabalho.. vou ate tentar ler o artigo em ingles com mais calma para ver de onde vc tirou essa inspiração.


--
http://ccppbrasil.github.io/
https://twitter.com/ccppbrasil
 
[&] C & C++ Brasil - http://www.ccppbrasil.org/
Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
---
Você recebeu essa mensagem porque está inscrito no grupo "ccppbrasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para ccppbrasil+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages