Jump to content

Validação de numero/letra


AFerreira_77
 Share

Recommended Posts

A função scanf devolve um número inteiro que pode ser utilizado para verificar se a leitura de dados foi correcta.

Neste caso, como estamos a ler apenas uma variável, o resultado esperado a ser devolvido pelo scanf é 1. Caso seja devolvido um valor inferior ao número de variáveis à "espera" de input, significa que houve um erro.

Exemplo:

if (scanf("%d%c%d", &n, &c, &m) != 3)
  printf("Erro de leitura");
else
  printf("Tudo ok");

Outros métodos existem e podem ser mais adequados conforme o caso.

Cumprimentos.

Knowledge is free!

Link to comment
Share on other sites

Olá,

Obrigado pela celeridade de respostas.

O ponto da questão onde reside as duvidas é:

- Quero que seja solicitado um numero (é expectável...) ao utilizador.

- Se fôr inteiro, continua e lê o próximo.

- Se fôr letra, salta fora de imediato e imprime "ERRO - Não é um numero", por exemplo...

O programa que pretendo está feito e a correr...contudo o que falta é encaixar um IF onde a linguagem "em português" traduza...se e quando entrar uma letra, termina o programa e o output imediato será "ERRO - Não é um numero".

Peço desculpa pela dúvida, mas estou a iniciar...e como já passei umas boas horas em volta deste pormenor, estou a pedir ajuda.

Obrigado

Cumprimentos

Link to comment
Share on other sites

AFerreira_77,

Uma vez que estás a iniciar a aprendizagem, deixa-me colocar-te uma questão: o enunciado desse problema que estás a resolver (estou a pressupor que haja um enunciado, mas pode não haver) indica especificamente que deverás rejeitar inputs inválidos?

A questão é que para quem está a começar, o importante é aprender como funciona a linguagem, etc e não tanto como validar o input do utilizador -- para isso terás que aprender a utilizar outras funções e trabalhar com strings.

Da forma que o código está neste momento, se alguém introduzir uma letra onde era de esperar um número, o teu programa entra num ciclo infinito, sendo necessário terminá-lo à força -- isso deve-se à forma como funciona a scanf -- mas não sei até que ponto será adequado partires já para a resolução desse problema.

Diz-nos o que pretendes relativamente ao que expus.

Link to comment
Share on other sites

Olá,

1) Quanto ao melhor espaçamento de caracteres no código, tem a sua razão de ser...contudo isso aconteceu porque eu estava a poupar uma tecla...ja que estou a programar em MAC.... ubuntu (através de uma maquina virtual)...e a maior parte dos caracteres são diferentes...logo tenho ao lado um post-it com as teclas. Assim ando de momento a lutar também com as teclas...lol (isto é um aparte pois o SPACE é o mesmo 😉 ), mas já agora, mais uma questão prós entendidos: Existe alguma forma de redefinir teclas no ubuntu -gedit- nestas circunstâncias?

2) O programa deve validar valores inteiros....! Ou seja, sempre que as entradas do scanf possuírem uma letra (em vez de numero), finda a leitura completa desse scanf, deve apresentar mensagem de "ERRO"...

Mais uma vez obrigado, pois às vezes é necessário pedir ajuda senão passamos metade do tempo disponível à procura de uma coisa simples...quando eu for um pro, também estarei disponível para ajudar sempre que possível..!

=================================

...

int p1x, p1y, p2x, p2y, p3x, p3y; //Variáveis do tipo inteiro para pontos (x,y)
printf("\n\n");
printf("Ponto1 ? "); scanf("%d %d", &p1x, &p1y); // Scanf do 1º ponto
printf("Ponto2 ? "); scanf("%d %d", &p2x, &p2y); // Scanf do 2º ponto
...  //	 => Aqui ou ANTES....falta um IF que verifica a entrada de dados, de modo que, enquanto for numero, CONTINUA...se fôr letra, salta fora do programa com a mensagem "ERRO - Não é numero...!"
...
return 0;
}

Ex OUTPUT: P(1,2); P(3,4); P(w,6); P(etc....)

Ponto1 ? 1 2

Ponto2 ? 3 4

Ponto3 ? w 6

ERRO - Não é numero...! //Já não continua a solicitar qualquer ponto mais..

Edited by apocsantos
tag code + geshi
Link to comment
Share on other sites

Alguém com ideia sobre o o presente assunto? Ainda não consegui lá chegar... ;(

Em relação ao partir para a resolução desse problema...é mesmo essa a intenção, é sempre a aviar mesmo que não queira...

Obrigado

A função scanf devolve um número inteiro que pode ser utilizado para verificar se a leitura de dados foi correcta.

Neste caso, como estamos a ler apenas uma variável, o resultado esperado a ser devolvido pelo scanf é 1. Caso seja devolvido um valor inferior ao número de variáveis à "espera" de input, significa que houve um erro.

Exemplo:

if (scanf("%d%c%d", &n, &c, &m) != 3)
  printf("Erro de leitura");
else
  printf("Tudo ok");

Outros métodos existem e podem ser mais adequados conforme o caso.

Cumprimentos.

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Como foi dito, o scanf é para ler apenas inteiros.

Da forma como está criado, podes ir escrevendo o que quiseres que enquanto não fizeres <enter> o C não assume o valor pelo que podes apagar tudo e voltar a escrever.

Para leres caracteres deves usar o gech ou o getche e para leres strings(palavras) deves usar o gets.

Dito isto e voltando à tua questão, se o scanf só deve ler inteiros, mas o utilizador é livre para "martelar" o que quiser no teclado, tens a necessidade de validares a entrada.

Assim podes fazer qualquer coisa como (também já dito):

if(scanf("%d",&n)==0) // deu erro
printf("ERRO");

se estás em ciclo, então deves ter uma variável de controlo

do{

estado=scanf("%d",&n);
if(estado==0)
printf("ERRO");

}
while(estado==1);
Edited by apocsantos
geshi
Link to comment
Share on other sites

Como foi dito, o scanf é para ler apenas inteiros.

Não exactamente.

Pode ler de tudo, mas aconselha-se principalmente para números (!= inteiros apenas).

Para leres caracteres deves usar o gech ou o getche e para leres strings(palavras) deves usar o gets.

Pode-se usar o getch e o gets, mas deve-se usar, respectivamente, o getchar (mais recomendado por ser standard, apesar de haver casos muitos específicos em que possa não ser o pretendido) e o fgets (altamente recomendado sobre o gets e o scanf).

Edited by thoga31

Knowledge is free!

Link to comment
Share on other sites

Não exactamente.

Pode ler de tudo, mas aconselha-se principalmente para números (!= inteiros apenas).

Pode-se usar o getch e o gets, mas deve-se usar, respectivamente, o getchar (mais recomendado por ser standard, apesar de haver casos muitos específicos em que possa não ser o pretendido) e o fgets (altamente recomendado sobre o gets e o scanf).

Concordo com a 1ª chamada de atenção porque foi falta de atenção minha.... quando disse inteiros seriam números.

não concordo com a solução do getchar pela mesma razão do scanf, precisa do enter. E se vais ler um caracter é só um. Não existe a noção de dois caracteres.

Relativamente ao fgets aceito que seja melhor.

NOTO no entanto, que as tuas observações pouco ajudarão o colega que colocou a questão.

Link to comment
Share on other sites

NOTO no entanto, que as tuas observações pouco ajudarão o colega que colocou a questão.

As minhas observações podem não ajudar na questão inicial do tópico - aliás, nesse ponto já dei os meus 2 cêntimos -, mas decerto que ajudarão a clarificar tanto o colega como qualquer leitor acerca de alguns pontos relativos a funções de input em C.

Não deixam de ser, em suma, observações potencialmente construtivas para a cultura geral de C de qualquer um - até porque inicialmente pretendia que fossem apenas pontuais -, e a troca de conhecimentos e experiência é um dos objectivos do P@P (não somos um fórum de mero Q&A) 😉

Knowledge is free!

Link to comment
Share on other sites

AFerreira_77,

O problema ao utilizares scanf sem verificar o seu resultado é que ao deparar-se com um input inválido este não é consumido, o que significa que, se estiveres a utilizar a scanf dentro de um ciclo, facilmente o ciclo se torna infinito: basta introduzir uma letra em vez de um número, a scanf não lê a letra (por não ser um número válido), e passas à próxima iteração do ciclo, na qual já existe input (tinha sido lá deixado pela invocação anterior da scanf) e novamente este é rejeitado, e não saímos disto.

A ideia do thoga31 de utilizar fgets não é nada má, e ficas sem necessidade de te preocupares com limpeza do buffer de input (e depois utilizas sscanf (tem mesmo dois 'ss') para analisar a string resultante de fgets).

leandroP,

A função scanf lê qualquer coisa, desde que seja um input que cumpra um determinado formato (que tu especificas no primeiro argumento). Queres ler números? Podes fazê-lo com scanf. Queres ler strings e chars? Também podes fazê-lo com scanf, sem problemas.

Quanto à utilização de getch e getche, o thoga31 tem razão: o correcto é utilizar getchar, fgets. Para começar, as funções getch e getche nem sempre estão disponíveis (não fazem parte do standard), e para concluir, a função gets sofre de terríveis problemas relativos a buffer overflow (que não existem na fgets).

Percebo a confusão ao reparar que mesmo com getchar é preciso dar ENTER, mas isso não se deve à getchar em si mas sim ao modo como o terminal/consola lida com o input e o agrupa (por linhas!) antes de o enviar para a aplicação. Por outras palavras, a getchar não precisa do ENTER, mas o teu sistema operativo (mais precisamente o teu terminal/consola) não envia para a aplicação a tecla que pressionaste enquanto não pressionares também a tecla ENTER. Há maneiras de contornar isto, mas todas são altamente dependentes do sistema operativo em causa.

  • Vote 1
Link to comment
Share on other sites

AFerreira_77,

Estuda este exemplo:

#include <stdio.h>

/* Definir o tamanho máximo do input do utilizador */
#define BUFFERSIZE 128

int main(void) {
 int n;
 char buf[bUFFERSIZE];

 printf("Número? ");
 /* Ler BUFFERSIZE-1 caracteres de input, armazená-los em buf */
 fgets(buf, BUFFERSIZE, stdin);

 /* Utilizar o valor de retorno da sscanf a nosso favor */
 if (sscanf(buf, "%d", &n) != 1)
   printf("Introduza um número válido!\n");
 else
   printf("O número introduzido foi %d.\n", n);

 return 0;
}

O exemplo em execução:

~ $ ./aferreira 
Número? ab
Introduza um número válido!
~ $ ./aferreira 
Número? 56
O número introduzido foi 56.
Link to comment
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
 Share

×
×
  • 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.