Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

bdexterholland

[Resolvido] Loop em uma string não acessa último Char

Recommended Posts

Olá galera,

 

 

Eu sumo, depois volto, depois sumo denovo...

 

...Tempo aperta muito e ultimamente quase não programo. Mas agora apareceu uma bobeira de cadastro de clientes :)

 

Assim, to fazendo a validação do CPF. Copiei uma função pronta do devMedia e adaptei para permitir CPFs digitados com ou sem os divisores (os pontos e o traço para formatação). O problema é que a forma que eu estou fazendo a função acontece um pau muito loko que remove o último caractere. Segue a função:

 

function TestaCPF(CPF : string) : boolean;
 var
   Dado : String;
   D1 : array[1..9] of byte;
   I,   DF1,  DF2,  DF3,  DF4,  DF5,  DF6,  Resto1,  Resto2,  PrimeiroDigito,  SegundoDigito : integer;
 begin
   Dado := '';
   for i := 0 to Length(CPF) - 1 do {O Pau tá neste loop, não sei porque ele não consegue acessar o último caractere}
	 if CPF[i] in ['0', '1', '2', '3','4', '5', '6', '7', '8', '9'] then
	   Dado := Dado + CPF[i];
   Result := true;
   if Length(Dado) = 11 then
	 begin
	   for I := 1 to 9 do
		 if Dado[I] in ['0'..'9'] then
		   D1[I] := StrToInt(Dado[I])
		 else
		   Result := false;
		   {$REGION 'Result =  true'}
		 if Result then
		   begin
			 DF1 := 0;
			 DF2 := 0;
			 DF3 := 0;
			 DF4 := 0;
			 DF5 := 0;
			 DF6 := 0;
			 Resto1 := 0;
			 Resto2 := 0;
			 PrimeiroDigito := 0;
			 SegundoDigito := 0;
			 DF1 := 10*D1[1] + 9*D1[2] + 8*D1[3] + 7*D1[4] + 6*D1[5] + 5*D1[6] + 4*D1[7] + 3*D1[8] + 2*D1[9];
			 DF2 := DF1 div 11;
			 DF3 := DF2 * 11;
			 Resto1 := DF1 - DF3;
			 if (Resto1 = 0) or (Resto1 = 1) then
			   PrimeiroDigito := 0
			 else
			   PrimeiroDigito := 11 - Resto1;
			 DF4 := 11*D1[1] + 10*D1[2] + 9*D1[3] + 8*D1[4] + 7*D1[5] + 6*D1[6] + 5*D1[7] + 4*D1[8] + 3*D1[9] + 2*PrimeiroDigito;
			 DF5 := DF4 div 11;
			 DF6 := DF5 * 11;
			 Resto2 := DF4 - DF6;
			 if (Resto2 = 0) or (Resto2 = 1) then
			   SegundoDigito := 0
			 else
			   SegundoDigito := 11 - Resto2;
			 if (PrimeiroDigito <> StrToInt(Dado[10])) or
				(SegundoDigito <> StrToInt(Dado[11])) then
			   Result := false;
		   end;
		   {$ENDREGION}
	 end
   else
	 if Length(Dado) <> 0 then
	   Result := false;
 end;

Alguém já viu algo assim?

Compartilhar este post


Link para o post
Compartilhar em outros sites

olha, talvez eu esteja falando besteira, mas faça um teste aí:

 

com objetos tipo TStringList e TMemo, a posição 0 é a primeira posição, porém em

variáveis do tipo string (que é o caso do parametro CPF), a primeira posição é 1...

 

então, ao invés do loop ser:

 

for i := 0 to Length(CPF) - 1 do

 

deveria ser:

 

for i :=1 to Length(CPF) do

 

 

faça um teste aí e post se deu certo...

 

 

abraços !!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Acho que eu tenho que revisar estes detalhes básicos dos tipos de dados do delphi. Eu estava analisando da seguinte forma: String de tamanho indefinido é um array dinâmico de chars e arrays dinâmicos tem como primeiro index com valor 0 (zero).

 

Bom, de volta as velhas apostilas.

 

Vlw pela ajuda....

Compartilhar este post


Link para o post
Compartilhar em outros sites

Gente, aproveitando, se alguem ler esse tópico, vou falar um pouco sobre arrays dinamicos em delphi

 

o Delphi, diferentemente do C++ (e outras linguagens), usa a posição "0" do vetor, para guardar seu tamanho.

Em arrays dinamicos, proceure não utilizar a ultima posição, sempre deixe o vetor com uma posição a mais do que se precisa, pois isso geralmente da erro

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

Caso queira uma função bacana pra teste de CPF..

 

function C_P_F( Dados: string ): boolean;
var
  Contar: integer;
  Digito: integer;
  Digito1: integer;
  Digito2: integer;
  Resto: integer;
  SemMascara: string;
begin
Digito1 := 0;
Digito2 := 0;
SemMascara := '';
for Contar := 1 to Length( Dados ) do
  begin
  if Pos( Copy( Dados, Contar, 1 ), '/-.' ) = 0 then
    SemMascara := SemMascara + Copy( Dados, Contar, 1 );
  end;
if Length( Trim( SemMascara ) ) < 11 then
  begin
    C_P_F := False;
    Exit;
  end;
Dados := SemMascara;
for Contar := 1 to 9 do
  begin
  Digito1 := Digito1 + ( ( 11 - Contar )
    * StrToInt( Copy( Dados, Contar, 1 ) ) );
   Digito2 := Digito2 + ( ( 12 - Contar )
    * StrToInt( Copy( Dados, Contar, 1 ) ) );
  end;
  Resto := Digito1 mod 11;
if Digito < 2 then Digito := 0
else Digito := 11 - Resto;
Digito2 := Digito2 + ( 2 * Digito );
Resto := Digito2 mod 11;
Digito := Digito * 10;
if Resto >= 2 then Digito := Digito + ( 11 - Resto );
if Digito <> StrToInt( Copy( Dados,
  10, 2 ) ) then C_P_F := False
else C_P_F := True;
end;

Eu uso essa e ela remove os traços de formatação

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado giovane,

 

A funcão que eu postei deu conta, após corrigir o problema de acesso ao ultimo char como foi feito seguindo a dica acima, a função caiu como uma luva...

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.