Achei interessante o algoritmo dos dígitos verificadores do CPF (Cadastro de Pessoa Física) e apresento o código-fonte em C++.
Para gerar o binário é necessário 3 arquivos:
1. Definição da classe
$ cat Cpfnum.h
#ifndef CPFNUM_H #define CPFNUM_H class Cpfnum { public: Cpfnum(); Cpfnum(const Cpfnum& orig); virtual ~Cpfnum(); int PrimeiroDigito(int, int, int, int, int ,int ,int, int, int); int SegundoDigito (int, int, int, int, int ,int ,int, int, int, int); private: #endif /* CPFNUM_H */
2. Definições das funções-membros da classe
$ cat Cpfnum.cpp
#include <iostream> using std::cout; using std::cin; using std::endl; #include <cstring> using std::string; #include "Cpfnum.h" Cpfnum::Cpfnum() { } Cpfnum::Cpfnum(const Cpfnum& orig) { } Cpfnum::~Cpfnum() { } int Cpfnum::PrimeiroDigito(int v1,int v2,int v3,int v4,int v5,int v6,int v7,int v8,int v9) { int m1, m2, m3, m4, m5, m6, m7, m8, m9; // multiplicado int soma, resto, v10; m1=v1*10; m2=v2*9; m3=v3*8; m4=v4*7; m5=v5*6; m6=v6*5; m7=v7*4; m8=v8*3; m9=v9*2; // somando m1 a m9 soma=m1+m2+m3+m4+m5+m6+m7+m8+m9; // obtendo o 1° dígito verificador: divisão da soma por 11 e o resto é o 1° dígito verificador resto=soma%11; if (resto < 2) v10=0; else v10=11-resto; return v10; } int Cpfnum::SegundoDigito (int v1,int v2,int v3,int v4,int v5,int v6,int v7,int v8,int v9, int v10) { int m1, m2, m3, m4, m5, m6, m7, m8, m9, m10; // multiplicado int soma, resto, v11; // novos valores multiplicados após encontrar o 1° dígito verificador m1=v1*11; m2=v2*10; m3=v3*9; m4=v4*8; m5=v5*7; m6=v6*6; m7=v7*5; m8=v8*4; m9=v9*3; m10=v10*2; // somando m1 a m10 soma=m1+m2+m3+m4+m5+m6+m7+m8+m9+m10; // divisão da soma por 11. Aplica-se regra do resto para encontrar o 2° dígito verificador resto=soma%11; if (resto < 2) v11=0; else v11=11-resto; return v11; }
3. Programa driver
$ cat main.cpp
#include <iostream> using std::cout; using std::cin; using std::endl; #include <cstring> using std::string; #include <sstream> using std::stringstream; #include <cstdlib> #include "Cpfnum.h" //using namespace std; int main(int argc, char** argv) { string mystring; string sv1, sv2, sv3, sv4, sv5, sv6, sv7, sv8, sv9, sv10, sv11; // sv10 = 1° dígito verificador e sv11 = 2° dígito verificador int v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11; // valor int pdv, sdv; // primeiro e segundo digito verificador cout << "Entre com o número do CPF: "; cin >> mystring; sv1=mystring[0]; sv2=mystring[1]; sv3=mystring[2]; sv4=mystring[3]; sv5=mystring[4]; sv6=mystring[5]; sv7=mystring[6]; sv8=mystring[7]; sv9=mystring[8]; stringstream(sv1) >> v1; stringstream(sv2) >> v2; stringstream(sv3) >> v3; stringstream(sv4) >> v4; stringstream(sv5) >> v5; stringstream(sv6) >> v6; stringstream(sv7) >> v7; stringstream(sv8) >> v8; stringstream(sv9) >> v9; if (mystring.length() < 9 || mystring.length() == 10 || mystring.length() > 11) cout << "Você digitou " << mystring.length() << " caracteres. Digite 9 ou 11." << endl; Cpfnum myCpfnum; myCpfnum.PrimeiroDigito(v1, v2, v3, v4, v5, v6, v7, v8, v9); myCpfnum.SegundoDigito(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); if (mystring.length() == 9) { v10=myCpfnum.PrimeiroDigito (v1, v2, v3, v4, v5, v6, v7, v8, v9); v11=myCpfnum.SegundoDigito (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); cout << v1 << v2 << v3 << v4 << v5 << v6 << v7 << v8 << v9 << "-" << v10 << v11 << endl; } if (mystring.length() == 11) { pdv=myCpfnum.PrimeiroDigito (v1, v2, v3, v4, v5, v6, v7, v8, v9); sdv=myCpfnum.SegundoDigito (v1, v2, v3, v4, v5, v6, v7, v8, v9, pdv); sv10=mystring[9]; sv11=mystring[10]; stringstream(sv10) >> v10; stringstream(sv11) >> v11; if ( (v10 == pdv ) && (v11 == sdv ) ) cout << "CPF válido!" << endl; else cout << "CPF inválido" << endl; } return 0; }
Considerações finais:
Uma IDE (Integrated Development Environment) faz muita diferença no desenvolvimento. Meus primeiros programas foram elaborados com o Anjuta, mas passei a usar o NetBeans.
O Anjuta cria as classes sem muitas instruções (virtual) o que considero bom para começar o contato com C++. No entanto, nada impede de iniciar com NetBeans e ignorar algumas funções-membros.
As IDEs vem com as configurações que buscam o compilador para gerar o binário. Caso prefira colar os respectivos conteúdo nos três arquivos com os nomes sugeridos, a linha de comando é:
$ g++ Cpfnum.cpp main.cpp -o cpf.out -ansi
E para escrever este texto usei o BlueFish. Claro que não deixei de usar o VIM, principalmente porque um recurso essencial como colar em colunas só encontro nele.