Jump to content
skinie18

Ciclo infinito (verificação de dados)

Recommended Posts

skinie18

Não sei se ja reparao mas em c se tivermos este codigo:

    int choice;

    while (0 == 0){
    printf("1. Dizer ola   2.Sair\n");
    scanf("%d", &choice);

    switch (choice) {
        case 1:
            printf("Ola  \n");
            break;
        case 2:
            exit(0);
            break;
        default:
            printf("Numero invalido! \n");
    }
    }

E um utilizador mal intencionado inserir um carácter do tipo char por exemplo, o programa faz ciclos infinitos!

Como previno estes bugs?

Share this post


Link to post
Share on other sites
Localhost
Return Value

On success, the function returns the number of items succesfully read. This count can match the expected number of readings or fewer, even zero, if a matching failure happens.

In the case of an input failure before any data could be successfully read, EOF is returned.


here since 2009

Share this post


Link to post
Share on other sites
skinie18

Return Value

On success, the function returns the number of items succesfully read. This count can match the expected number of readings or fewer, even zero, if a matching failure happens.

In the case of an input failure before any data could be successfully read, EOF is returned.

ou seja se correr mal o retorno do scanf será end of file, entao isto deveria resolver:

    verify = scanf("%d", &choice);
    if (verify == EOF)
    choice = 10;

Não resolve!

Nem isto:

    verify = scanf("%d", &choice);
    if (verify != 0)
        choice = 10;

Share this post


Link to post
Share on other sites
skinie18

Encontrei aqui no portugal a programar noutros posts uma solução: scanf("%*[^\n]%*c");

    int choice;

    while (0 == 0){
    printf("1. Dizer ola   2.Sair\n");
    scanf("%d", &choice);
    scanf("%*[^\n]%*c");

    switch (choice) {
        case 1:
            printf("Ola  \n");
            break;
        case 2:
            exit(0);
            break;
        default:
            printf("Numero invalido! \n");
    }
    }

É correcto assim o código?

Share this post


Link to post
Share on other sites
brunoais

Parece-me não ser seguro...

Acho que só com um fread é que conseguirias algo suficientemente seguro... (preciso de ajuda para arranjar uma resposta mais apropriada)


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Share this post


Link to post
Share on other sites
daj

Devias atribuir um valor inicial a choice ou validar o retorno do primeiro scanf. Assim, se por acaso estiver lá o valor 1, podes ter o seguinte comportamento:

1. Dizer ola   2.Sair
aaaa
Ola 

brunoais, porque é que não te parece seguro?

Share this post


Link to post
Share on other sites
skinie18

Devias atribuir um valor inicial a choice ou validar o retorno do primeiro scanf. Assim, se por acaso estiver lá o valor 1, podes ter o seguinte comportamento:

1. Dizer ola   2.Sair
aaaa
Ola 

brunoais, porque é que não te parece seguro?

Mesmo que a validação dê que não foi recebido um int, os caracteres vão ficar em buffer e vou ter que usar algo para os tirar de la!

Share this post


Link to post
Share on other sites
daj

Sim, não comentei quando ao segundo scanf. Se não for recebido um int, e depois de removeres os caracteres, ainda assim vais entrar no switch sobre um valor que não sabes qual é. O primeiro scanf, ao falhar, não altera o valor de choice.

Quanto ao segundo scanf, parece interessante. Estive a ler alguma documentação e deixo a seguinte sugestão. Talvez queiras alterar o scanf para:

scanf("%*[^\n]");

Com o scanf("%*[^\n]%*c"), se for introduzido "12abc<enter>", choice fica com 12, %*[^\n] consome "abc" e %*c consome o enter, ficando o buffer vazio. Se for introduzido "12<enter>", choice fica com 12 e o segundo scanf falha, ficando o buffer com "<enter>". Isto acontece porque

[ Matches a non-empty sequence of bytes from a set of expected bytes (the scanset).

Com o scanf("%*[^\n]"), se for introduzido "12abc<enter>", choice fica com 12, %*[^\n] consome "abc" e o buffer fica com "<enter>". Se for introduzido "12<enter>", choice fica com 12 e o segundo scanf falha, ficando o buffer com "<enter>".

A menos que um scanf a seguir comece com um %c ou um %[, o enter deixado no buffer não faz mal. No entanto, se o quiseres remover também, podes fazer:

scanf("%*[^\n]");
scanf("%*c");

que não é a mesma coisa que scanf("%*[^\n]%*c");

Share this post


Link to post
Share on other sites
Localhost

Se as tuas opções forem de 0 até 10, deixo-te aqui uma solução:

#include <stdio.h>

int main (void)
{
    char charlol;
    int intlol = 0;

    scanf ("%c", &charlol);
    if (isdigit (charlol) != 0)
    {
intlol = atoi (&charlol);
printf ("%d\n", intlol);
    }
    else
printf ("Error!\n");

    return 0;
}


here since 2009

Share this post


Link to post
Share on other sites
bubulindo

Não sei se ja reparao mas em c se tivermos este codigo:

    int choice;

    while (0 == 0){
    printf("1. Dizer ola   2.Sair\n");
    scanf("%d", &choice);

    switch (choice) {
        case 1:
            printf("Ola  \n");
            break;
        case 2:
            exit(0);
            break;
        default:
            printf("Numero invalido! \n");
    }
    }

E um utilizador mal intencionado inserir um carácter do tipo char por exemplo, o programa faz ciclos infinitos!

Como previno estes bugs?

Eu posso estar errado, mas quando fazes while (0==0), não é um ciclo infinito que pretendes?

Também não percebi exactamente porque não usas um getchar em vez de scanf... se não ultrapassares a dezena de opcões, parece-me que resolve o problema.


include <ai se te avio>

Mãe () {

}

Share this post


Link to post
Share on other sites
xtrm0

Nao, o exit serviria para fechar a aplicaçao.

O ciclo infinito decorreria até a aplicação ser fechada, mas se um utilizador em vez de um numero metesse "a", a aplicacao nao voltaria a pedir nennhum caracter, repetindo o ciclo infinitamente.


<Signature goes here>

Share this post


Link to post
Share on other sites
xtrm0

Usa:

    verify = int(scanf("%d", &choice));

    assim se o utilizador meter uma letra, esta sera convertida para int, ou a aplicaçao abortará em vez de ciclo infinito.

    Outra forma é usares:

char *a;
int n=0;
cin >> a;
for (i=0; i<a.lenght; i++) {
if (a[a.lenght-i-1]>=50 && a[a.lenght-i-1]<60){
n=n+(int(char(a[a.length()-i-1])-char('0'))*10^i;
} else {cout << erro; exit(1);}
}

Nota: o sintaxe nao esta certo,


<Signature goes here>

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.