Hello, the main problem of storing number with zero start starts when the number has more than 7 digits, as is the case of the CPF. The compiler believes that when a number has more than 7 digits and starts with zero it is from base 8. Causing some problems for us. The best option is to store the numbers in this case as a string.
For example, to check if the number of numbers is correct we could do something like:
#include <stdio.h>
#include <string.h>
int checkCPF(char* cpf) {
printf("CPF como string: %s \n", cpf);
printf("Números do CPF: %lu \n", strlen(cpf));
if(strlen(cpf)==11) {
return 1;
}
return 0;
}
int main() {
char* cpfA = "18315228889";
char* cpfB = "0031522888";
checkCPF(cpfA);
checkCPF(cpfB);
return 0;
}
But this is not very practical if you are to work with the numbers themselves, perform some type of validation or take only a part of the number, in this case we can use a CPF structure, you can implement its structure the way you want , for example:
typedef struct _CPF{
unsigned int a;
unsigned int b;
unsigned int c;
unsigned int verificador;
} CPF;
It's a very simple structure, and you can work with numbers in isolation.
To get the full CPF as a long int
you can use a function like:
long int getCPFCompleto(CPF cpf) {
long int cpfCompleto = 0;
char buffer[12];
char* fixEnd;
sprintf(buffer, "%d%d%d%d", cpf.a, cpf.b, cpf.c, cpf.verificador);
cpfCompleto = strtol (buffer,&fixEnd,10);
return cpfCompleto;
}
Of course, if the CPF has the first number 0 in any of the elements this can cause problems so it is better to return the value as a string again.
The logic is complete. I will post only the complete commented code and hope that I can help you with something.
#include <stdio.h>
#include <stdlib.h> // malloc
// Nossa estrutura básica para armazenar o CPF
typedef struct _CPF{
unsigned int a;
unsigned int b;
unsigned int c;
unsigned int verificador;
} CPF;
// Retorna o CPF completo
// É possivel informar se queremos o número formatado ou não
void getCPFCompleto(char* buffer, CPF cpf, int formatado) {
long int cpfCompleto = 0;
// Aqui está um ponto fundamental
// Perceba que informmos %03d informando que esperamos 3 dígitios
// Caso ele conter menos que 3 digitos ele adiciona zero a esquerda.
// Execeto no número verificado com 2 dígitos
if(formatado)
sprintf(buffer, "%03d.%03d.%03d-%02d", cpf.a, cpf.b, cpf.c, cpf.verificador);
else
sprintf(buffer, "%03d%03d%03d%02d", cpf.a, cpf.b, cpf.c, cpf.verificador);
}
// Populamos nossa variavel CPF
void populateCPF(CPF* cpf, char* cpfString, int formatado) {
if(formatado)
sscanf(cpfString, "%03u.%03u.%03u-%02u", &cpf->a, &cpf->b, &cpf->c, &cpf->verificador);
else
sscanf(cpfString, "%03d%03d%03d%02d", &cpf->a, &cpf->b, &cpf->c, &cpf->verificador);
}
int main() {
CPF mCPF;
char* cpfCompleto;
// Alocamos 15 caso o valor retornado possuir formatação
cpfCompleto = (char*) malloc(15*sizeof(char));
// Passamos nossa o ponteiro para nossa variavel CPF
// O CPF para ser formatado como string
// E se o número é formatado ou não
populateCPF(&mCPF, "08315228802", 0);
// Podemos imprimir os elementos de forma unitaria
printf("CPF A: %03d\n", mCPF.a);
printf("CPF B: %03d\n", mCPF.b);
printf("CPF C: %03d\n", mCPF.c);
printf("CPF Verificador: %02d\n", mCPF.verificador);
// Podemos imprimir o número completo utilizando a função
// getCPFCompleto
// Informamos um ponteiro para char a variavel com o CPF
// e se queremos formatada ou não
getCPFCompleto(cpfCompleto, mCPF, 0);
printf("O número do CPF completo é: %s \n", cpfCompleto);
// Vamos liberar a memoria do buffer
free(cpfCompleto);
return 0;
};