Ir para o conteúdo
AFerreira_77

Validação de numero/letra

Mensagens Recomendadas

AFerreira_77

Olá

Venho solicitar ajuda sobre:

- a forma de validar um inteiro, em linguagem simples e sob condição (if)

....

....

int num;

printf("numero?\n");

scanf("%d",&num);

....

....

Ex do OUTPUT: numero? 1 .........(continua)

numero? a...........printf("ERRO - Não é numero..!");

Obrigado

Tá agradecido

Abraços

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
thoga31

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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
AFerreira_77

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
AFerreira_77

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

Editado por apocsantos
tag code + geshi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
AFerreira_77

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
leandroP

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);

Editado por apocsantos
geshi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
thoga31

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).

Editado por thoga31

Knowledge is free!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
leandroP

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
thoga31

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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

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.

  • Voto 1

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.