Jump to content
NEMESISaka

Repeat Until + Enter

Recommended Posts

NEMESISaka

Boas...

Tenho um problema neste código:

writeln('Idade');
                        {testar se tecla ‚ char ou numero}
                        repeat
                        c:=readkey;
                        if c in ['0'..'9'] then
                        write(c)
                        else
                        writeln('Por favor intruduza um número') ;
                        until ord(a)=0;
                        {fim de teste}

o que acontece é o seguinte, quando o programa corre, caso se introduza uma letra, ele realmente manda a mensagem do else, no entanto, só o faz uma vez e se nos tentarmos apagar um numero com o "backspace", caso tenhamos errado no valor, já não será possível...

Enquanto ao Ord(a)=0 eu li em alguns fóruns que o numero correcto era o 13 para a tecla enter, mas com o 13 ou #13 o programa mandava sempre a mensagem do else após o enter e não prosseguia em frente, no entanto também achei um programa em pascal para saber o numero a que o enter estava associado e dizia-me que era ao 0 e ao 28 (em mensagens distintas)...

Por isso, se alguém tiver alguma sugestão agradeço e deixo desde já um obrigado a todos os que queiram ajudar...

Share this post


Link to post
Share on other sites
Vinícius.

São necessárias mais linhas de código para funcionar corretamente (incluindo o backspace). Você pode:

a) ler uma variável string e depois convertê-la para integer ou real:

program teste_VAL;
uses
 crt;
var
 entrada: string;
 numero, teste_erro: integer;
begin
 while true do
   begin
     readln(entrada);                   //receber string
     val(entrada, numero, teste_erro);  //converter para número
     if teste_erro = 0 then             //se não houve erro
       writeln('N',#233,'MERO ',numero:0)          //imprimir o número
     else                               //se houve erro
       writeln('ERRO');                            //imprimir 'ERRO'
   end;
end.

ou:

b) criar um procedure "um pouco" grande para substituir o readln no programa principal.

Já fiz algo parecido antes:

http://www.portugal-a-programar.pt/forums/topic/0-find-topic/?do=findComment&comment=354553

Dica: para pôr um código no fórum, selecione a linguagem para que apareça com realce de sintaxe.

seu código

Share this post


Link to post
Share on other sites
NEMESISaka

Obrigado pela a ajuda, vou tentar então...

Em questão ao meter a linguagem no post, já tinha tentado mas não tinha conseguido, pois não sabia bem como meter, mas obrigado por me ensinar^^

Edit: Não consegui fazer muita coisa disto, pois ele só verifica a primeira tecla...

Após o primeiro numero estar dentro do que é aceitavel ele para...

vou postar o código, caso alguém tenha sugestões...

Program trab2 (input,output);

uses crt;

const
Npessoas = 15;
enter=[chr(13),chr(28),chr(0)];
backspace=[chr(8)];
algarismos=['0'..'9'];

type
dados = array[1..Npessoas] of record
idade: integer;
peso, altura: real;
olhos, cabelo: string;
end;

var
pessoa: dados;
cont, pes5060, alt, med_idade, azul: integer;
medtotal, azulper: real;
c, a: char;

aceitar:set of chr(0)..chr(255);

begin
        clrscr;
        writeln('Bem-Vindo');
        writeln('Este programa ir  fazer alguns calculos para si, ');
        write('no entanto ser  preciso a informa‡Æo de 15 pessoas,');
        writeln('em que ‚ necessario a idade, o peso, a altura, a cor dos olhos e do cabelo');
        cont:=0;
                while cont<15 do
                begin
                        aceitar:=['0'..'9',chr(13),chr(8),chr(0),chr(28)];
                        inc(cont);
                        writeln('',cont,'¦ Pessoa, por favor intruduza:');
                        writeln('Idade');
                        {testar se tecla ‚ char ou numero}
                        repeat
                         repeat
                          c:=readkey;
                         until c in aceitar;
                          if c in ['0'..'9'] then
                            write(c)
                          else
                          writeln('Por favor intruduza um n£mero') ;
                        until (ord(a)=13) or (ord(a)=28) or (ord(a)=0);
                        {fim de teste} 

Já tentar mudar a variável c para string, mas depois ai da erro...

Vinícius... se poder pode-me explicar um pouco do procedure, em que consiste e como utilizar...

Obrigado desde ja...

Share this post


Link to post
Share on other sites
nunopicado

NEMESISaka:

Há ali uma coisa que não estou a perceber...

Estás a ler a variável 'C', mas no último until estás a testar a variável 'A'?

Ou falta aí algum bocado de código, ou eu estou a ver mal.

De qualquer maneira, depois do 1º until eu tiraria o if e punha antes um case. Ficaria algo do género:

Program trab2 (input,output);

uses
    crt;

const
     Npessoas = 15;

     type
    dados = array[1..Npessoas] of record
        idade: integer;
        peso, altura: real;
        olhos, cabelo: string;
    end;

var
   pessoa: dados;
   cont, pes5060, alt, med_idade, azul: integer;
   medtotal, azulper: real;
   c, a: char;
   aceitar:set of chr(0)..chr(255);

   savedx, { Guarda a posição do horizontal do cursor quando é preciso dar o aviso, para depois voltar à posição inicial }
   idade, { Guarda temporariamente a idade durante a conversão para inteiro - Não é obrigatório, pode-se inserir no val() directamente o pessoa.idade. Simplesmente gosto mais do código assim }
   errcode:integer; { Guarda o código devolvido pelo val() 
   s:string; { Guarda o conjunto de teclas aceites lidas, para no final fazer a conversão para inteiro }

begin
     clrscr;
     writeln('Bem-Vindo');
     writeln('Este programa ir  fazer alguns calculos para si, ');
     write('no entanto ser  preciso a informação de '+npessoas+' pessoas,');
     writeln('em que ‚ necessario a idade, o peso, a altura, a cor dos olhos e do cabelo');
     cont:=1;  { Alterei para 1 pois passei o inc(cont) para o fim do loop, de modo a que, apenas se o valor da idade for válido ele passa a pedir a idade da pessoa seguinte }
     while cont<=npessoas do
        begin
             writeln(cont,'º Pessoa, por favor intruduza:');
             writeln('Idade');
             {testar se tecla ‚ char ou numero}

             s:='';
             repeat
                   c:=readkey; 
                   case c of
                        '0'..'9':begin    { Se a tecla for numerica, escreve-a no ecran e soma-a à variavel s, para guardar o valor total }
                                      write(c);     
                                      s:=s+c;
                                 end;
                        #8:begin   { Se for pressionado o backspace, volta um caracter atrás, limpa-o, e fica na posição inicial }
                                gotoxy(wherex-1,wherey);
                                clreol;   { Limpa a linha desde a posição do cursor até ao fim }
                           end;
                        #13:writeln;  { Se for pressionado o enter, muda de linha }
                   else begin   { se a tecla pressionada não for aceitável, guarda a posição do cursor, escreve a mensagem de erro, e ao fim de dois segundos, apaga-a e deixa o curos na posição inicial }
                             savedx:=wherex;
                             write('  Só são aceites caracteres numéricos. . .');
                             delay(2000);
                             gotoxy(savedx,wherey);
                             clreol;
                        end;
                   end;
             until c=#13;   { Se a tecla for enter, termina o ciclo de entrada de um valor }
             val(s,idade,errcode);   { converte o valor em s para inteiro }
             if errcode=0 then begin    { se a conversão for bem sucedida, guarda o valor no registo e incrementa o contador }
                                    pessoa[cont].idade:=idade;
                                    inc(cont);
                               end;
        end;


end.

Espero que ajude...

De qualquer maneira, qq coisa é só dizer!


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
NEMESISaka

Obrigado desde de já pela a ajuda...

Então, o "c" era para testar o carácter e o "a" era para quando se pressiona o enter...

Mas estou quase com um problema que tinha anteriormente, quando pressiono o enter, ele não aceita o primeiro valor, só aceita a 2ª idade inserida...

Mas amanha vou batalhar mais um pouco com o pascal, rever as linhas de código e ver se consigo alguma coisa...

Outra coisa que reparei agora, quando se introduz um numero e depois clica-se no backspace, o "traço" volta para traz mas os números não desaparecem...

Bem, mas isso é uma coisa que eu acho que consigo resolver amanha, desde de já, muito mas mesmo muito obrigado pelo post e por teres metido o significado das coisas no código^^

Share this post


Link to post
Share on other sites
nunopicado

Então, o "c" era para testar o carácter e o "a" era para quando se pressiona o enter...

Não é necessário. A variável a ler é sempre a mesma, pelo que basta o 'c'. Depois é só testar essa para ver se tem os valores aceitáveis (no caso, 0 a 9, enter e backspace);

Mas estou quase com um problema que tinha anteriormente, quando pressiono o enter, ele não aceita o primeiro valor, só aceita a 2ª idade inserida...

hmmmm Experimenta rodar a minha versão, esse problema não existe lá. pode haver alguma variável não/mal inicializada que cause isso.

Outra coisa que reparei agora, quando se introduz um numero e depois clica-se no backspace, o "traço" volta para traz mas os números não desaparecem...

Depois de voltar atrás, usa um clreol; para limpar a linha até ao final. assim o cursor fica na posição correcta e o caracter que lá estiver desaparece.

Bem, mas isso é uma coisa que eu acho que consigo resolver amanha, desde de já, muito mas mesmo muito obrigado pelo post e por teres metido o significado das coisas no código^^

;) Sempre às ordens... :) Os comentários são uma boa prática para qualquer programador.

Mesmo quando o código só será lido por nós, o que lembramos perfeitamente agora, poderá estar esquecido amanhã, e é aó que os comentários entram no paraíso :D :D


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
NEMESISaka

Já testei...

E o código funciona, mas faltava uma coisa...

Pois quando um utilizador pressionava o enter  sem escrever la nada ele aceitava na mesma...

Mas no until eu adicionei mais uma condição, e então ficou "until (c=#13) and (s<>'');"

Agora já trabalha...

Muito obrigado por tudo^^

Topic solved...

Edit: adicionei também mais uma condição:

if s='' then
writeln('Por favor introduza um valor');
until (c=#13) and (s<>'');

Share this post


Link to post
Share on other sites
nunopicado

Isso mesmo!  ;)

E se quiseres, nesse ultimo if, podes incluir o código do else, de modo a que o cursor, apos a mensagem de erro, fique no mesmo lugar, mantendo a estrutura "visual" do programa.

Ficaria assim:


if s='' then begin
                     SavedX:=WhereX;
                     Write(' Por favor introduza um valor. . .');
                     delay(2000);
                     GotoXY(SavedX,WhereY);
                     ClrEOL;
                  end
         else Writeln;

São mais umas linhas, mas acho que vale a pena...  :D

Neste caso, não ficaria no fim do loop, mas na opção #13 do case, de modo a que, se o utilizador só der <enter>, o programa não chega a mudar de linha, dando a mensagem de erro na linha onde estava a fazer a pergunta, e mantendo-se lá...

Já agora, corrigindo o meu proprio esquecimento, na opção #8 do case, levaria mais um if:


#8: if WhereX>1 then begin
                                         gotoxy(wherex-1,wherey);
                                         clreol;
                                   end;

Assim, se o cursor já estiver na primeira posição, não tenta voltar mais ainda, pois não faria sentido e provavelmente (não testei) daria erro...


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.