Hello, the main problem of storing number with zero start starts when the number has more than 7 digits, as is the case with 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 amount 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 going to work with the numbers themselves, perform some kind of validation or take only a part of the number, in this case we can use a CPF structure, you can implement your structure however 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 the 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 CPF has the first number 0 in any of the elements it can cause problems then it is better to return the value as a string again.
The logic is complete. I will post only the full code commented and hope I can assist you in 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;
};
With numerics you simply add the zeros to the left when displaying. Char spends more space than it needs, but stores it in a very predictable way (and would have no problem ordering from left to right). In the middle of the field you would have the BCD, but then you would require some more specific functions. It would be nice to give details of the specific problem, and the ultimate goal of what you are doing (usually the focus on the goal is better than the focus on the current attempt).
– Bacco