Jump to content

Ajuda em Exercicio: protecção contra letras ao fazer input de números


Recommended Posts

Posted

Boas pessoal

Sou novo nisto na programação, e tenho aqui uma duvida num exercicio.

Escreva um programa que calcule o preço que um determinado aluno deverá pagar

de propinas sabendo que o montante a pagar por cada disciplina é 50 €, no entanto,

se o número de anos ao qual está inscrito a essa disciplina estiver compreendido

entre 2 e 4 inclusive, deverá ser paga uma taxa adicional de 15% e se for superior a

4 anos uma taxa de 25%.

Já consegui revolver o exercicio, mas agora foi me pedido que o protege-se contra numeros negativos e contra letras.

Os numeros negativos já está feito, mas não estou a ver como e que vou fazer para as letras??

O codigo é este:

#include <stdio.h>
#include <stdlib.h>
/*
*
*/
int main(int argc, char **argv)
{
   int ano;
   int disciplinas;
   int propinas;
   float taxa;
   float total;
   int continuar;
   int sair;

   char euro;
   char a;
   char a1;
   char e;
   char c;
   char o;
   char o1;
   char u;

   euro = 128;
   a = 225;
   a1 = 227;
   e = 233;
   c = 231;
   o = 243;
   o1 = 245;
   u = 250;

   continuar = 0;

   while (continuar <= 0) { 
printf("###Pode Calcular aqui o pre%co das suas Propinas###nn", c);

printf("--> Introduza o n%cmero de disciplinas:n", u);
scanf("%d", &disciplinas);

printf("--> Introduza o n%cmero de anos:n", u);
scanf("%d", &ano);

if (disciplinas <= 0 || ano <= 0) {
    printf("nN%co pode introduzir n%cmeros negativos!n", a1, u);
} else {
    if (disciplinas > 999 || ano > 999) {
	printf("nN%co pode introduzir n%cmeros superiores a 999n", a1, u);
    } else { 
	if (ano == 2 || ano == 3 || ano == 4) {
	    propinas = disciplinas * 50;
	    taxa = propinas * 0.15;
	    total = propinas + taxa;
	    printf("n- O valor das propinas %c de %d%cn", e, propinas, euro);
	    printf("- Ter%c de pagar uma taxa adicional de %.2f%c n", a, taxa, euro);
	    printf("- No total ter%c de pagar %.2f%cn", a, total, euro);
	} else {
	    if (ano > 4) {
		propinas = disciplinas * 50;
		taxa = propinas * 0.25;
		total = propinas + taxa;
		printf("n- O valor das propinas %c de %d%cn", e, propinas, euro);
		printf("- Ter%c de pagar uma taxa adicional de %.2f%cn", a, taxa, euro);
		printf("- No total ter%c de pagar %.2f%cn", a, total, euro);
	    } else {
		propinas = disciplinas * 50;
		printf("n- O valor das propinas %c de %d%cn", e, propinas, euro);
		printf("- N%co ter%c de pagar nenhuma taxa adicionaln", a1, a);
		printf("- No total ter%c de pagar %d%cn", a, propinas, euro);
	    }
	}
    }
}

printf("nDeseja continuar o Programa?n");
printf("Para continuar pressione a tecla [1] para sair pressione a tecla [0]n");
scanf("%d", &sair);

if (sair == 1) {
    printf(" \033[2J");
           continuar = sair*continuar;
       }
       else
       {
           break;
       }

Obrigado

Posted (edited)

pois, notasse que és novo porque a indentação é horrível ...

não vou usar unsigned int para te mostrar como fazer a verificação :

int read_positive_integer(const char * message)
{
 int value = -1;   // variável que guardará o valor inserido a ser retornado
 int ok = 0;       // variável que guarda o valor booleano que dita se o valor foi correctamente lido
 char buffer[256]; // buffer de leitura do teclado

 while (!ok)                          // enquanto o valor não foi correctamente lido
 {
   printf("%s : ", message);          // apresentar a mensagem
   fflush(stdout);                    // forçar a apresentação da mensagem
   fgets(buffer, 256, stdin);         // ler tudo o que se encontra no buffer de leitura do teclado
   ok = sscanf(buffer, "%d", &value); // ler o valor numérico, se foi correctamente lido, a função retorna 1
   if (value <= 0)                    // verifica se o valor lido não é positivo
     ok = 0;                          // então marcar como não válido
 }

 return value;                        // retornar o valor lido
}

int value = read_positive_integer("Insira um valor inteiro positivo"); // chamar a função
Edited by HappyHippyHippo
IRC : sim, é algo que ainda existe >> #p@p
Posted

O scanf() devolve o n'umero de atribuições correctamente efectuadas.

Tens de verificar se o valor devolvido pelo scanf() corresponde ao que estás à espera; se não corresponder é porque os dados não estavam de acordo com o esperado.

if (scanf("%d", &disciplinas) != 1) { /* dados errados, abortar o programa */ }

if (scanf("%d", &ano) != 1) { /* dados errados, abortar o programa */ }

Um exemplo mais complexo, com três variáveis ... mas com o corpo do if preenchido

if (scanf("%d%d%d", &ano, &mes, &dia) != 3) {
   printf("Data inválida. Programa abortado.\n");
   exit(EXIT_FAILURE);
}

Nota que abortar o programa não é, necessariamente, a melhor coisa a fazer. Numa fase lá mais para a frente, podes ignorar os dados com erro e pedir ao utilizador para tentar novamente.

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

Mas assim o utilizador só vai conseguir introduzir numeros de 1 a 9. E eu queria que o utilizador podesse introduzir numeros de 1 até 999

Como e que eu vou fazer assim..

Não, não, não!

O scanf() devolve o número de atribuições efectuadas com sucesso.

Se o scanf() atribuir 999 à variável devolve 1; se ele atribuir 42 a uma variável e 17420003 a outra devolve 2.

Também podes obter o número de caracteres usados pelas atribuições, mas, sinceramente, nunca vi isso usado (lê sobre a especificação "%n").

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted (edited)

Obrigado pela ajuda 😄

Tentei incluir a parte do scanf() no meu programa e não estou a conseguir, está sempre com um erro. Será que estou a fazer mal?

printf ("--> Introduza o n%cmero de disciplinas:\n",u);
if (scanf("%d", &disciplinas) != 1){
    printf ("caracter invalido\n");
    break;
}


printf ("--> Introduza o n%cmero de anos:\n",u);
if (scanf("%d", &ano) != 1){
    printf ("caracter invalido\n");
    break;
}

inclui nesta parte

Edited by pmg
Falta LP
Posted

Quando o scanf() "apanha" um caracter invalido, não o tira do input. Esse mesmo caracter inválido vai ser apanhado pelo scanf() seguinte.

No teu caso, ao introduzir, por exemplo, "duas<ENTER>" para o número de disciplinas o scanf() devolve 0 e imprime a mensagem.

Mais à frente, o scanf() seguinte apanha "duas<ENTER>" e devolve 0 também e assim sucessivamente até ao infinito.

Solução apresentada anteriormente por mim: abortar o programa. Quando o utilizador executar o programa a seguir recomeça com um input vazio.

Outras soluções:

a) usa fgets() e sscanf() para ler input

b) limpa o buffer de input em caso de erro (com getchar() até ao <ENTER>)

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted (edited)

Não estou a conseguir perceber, o que me estas a tentar explicar :s

Essas outra soluções que me apresentas-te ainda não as conheço, não posso utiliza-las...

Está aqui o meu programa, que tenho ate agora.

#include <stdio.h>
#include <stdlib.h>
/*
*
*/
int main(int argc, char** argv) {
int ano;
int disciplinas;
int propinas;
float taxa;
float total;
int continuar;
int sair;


char euro;
char a;
char a1;
char e;
char c;
char o;
char o1;
char u;


euro = 128;
a = 225;
a1 = 227;
e = 233;
c = 231;
o = 243;
o1 = 245;
u = 250;


continuar=0;


while(continuar<=0)
    {



printf ("###Pode Calcular aqui o pre%co das suas Propinas###\n\n",c);

printf ("--> Introduza o n%cmero de disciplinas:\n",u);
scanf ("%d",&disciplinas);

printf ("--> Introduza o n%cmero de anos:\n",u);
scanf("%d",&ano);

            if (ano==2||ano==3||ano==4)
            {
            propinas = disciplinas * 50;
            taxa = propinas * 0.15;
            total = propinas + taxa;
            printf ("\n- O valor das propinas %c de %d%c\n", e, propinas, euro);
            printf ("- Ter%c de pagar uma taxa adicional de %.2f%c \n", a, taxa, euro);
            printf ("- No total ter%c de pagar %.2f%c\n", a, total,euro);

            }
                    else
                    {
                            if(ano > 4)
                            {
                            propinas = disciplinas * 50;
                            taxa = propinas * 0.25;
                            total = propinas + taxa;
                            printf ("\n- O valor das propinas %c de %d%c\n", e, propinas, euro);
                            printf ("- Ter%c de pagar uma taxa adicional de %.2f%c\n", a, taxa, euro);
                            printf ("- No total ter%c de pagar %.2f%c\n", a, total, euro);

                            }
                                    else
                                    {
                                    propinas = disciplinas * 50;
                                    printf ("\n- O valor das propinas %c de %d%c\n", e, propinas, euro);
                                    printf ("- N%co ter%c de pagar nenhuma taxa adicional\n",a1,a);
                                    printf ("- No total ter%c de pagar %d%c\n", a, propinas, euro);
                                    }
                                    }





    printf("\nDeseja continuar o Programa?\n");
    printf("Para continuar pressione a tecla [1] para sair pressione a tecla [0]\n");
    scanf("%d",&sair);

    if (sair==1)
            {
            printf(" \033[2J");
            continuar = sair*continuar;

            }
    else
            {
            break; /* continuar = saida+1;*/
            }
}

Podes-me me dizer onde ou como e que tenho de fazer para me resolver a situação?

Edited by pmg
Falta LP
Posted

Como te sugeri no post #4, mete os scanf() dentro dum if e termina o programa se o scanf() não for válido.

Se não queres usar a macro EXIT_FAILURE, podes usar um valor qualquer no exit(), por exemplo, 42 (o usual é 0 significar sucesso e qualquer outro valor significar insucesso).

A função exit() é uma função da biblioteca Standard do C. Se ainda não a conheces e não a quiseres usar, podes fazer um return 42; que tem um efeito muito parecido no caso em que o teu programa é composto unicamente pela função main().

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

Já consegui, que o programa me detectasse as letras, mas eu não queria que o meu programa terminasse logo. Queria que ao detectasse uma letra fizesse um printf() a dizer que não era um caracter válido e me continua-se o ciclo while para me voltar ao inicio do programa.

O meu prof falou-me de bloquear as letras com a tabela ascii, como e que se fazia assim?

Obrigado pela ajuda 🙂

Posted (edited)

Quais destas operadores / instrucoes / funcoes podes usar: !, if, while, getchar(), fgets(), strtol(), isdigit(), sscanf()?

Podes usar arrays? Se nao, como é que mexes com strings?

Edited by pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

Se nao podes usar nenhuma das funcoes indicadas por mim, so e possivel se poderes usar arrays (para input de string com o scanf()).

Se nao podes usar arrays (para input de strings) acho que é impossivel.

Gostava de ver a solucao do teu professor ... 🙂

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

acho que a solução que o professor espera seria algo dentro destes moldes

char sair; // um caracter

do
{
 printf("\nDeseja continuar o Programa?\n");
 printf("Para continuar pressione a tecla [1] para sair pressione a tecla [0]\n");
 scanf("%c",&sair); // ler um caracter
 if (sair != '1' && sair != '0')
   printf("valor lido invalido : %c\n", sair);
} while (sair != '1' && sair != '0');

continuar = !(sair - '0');

agora no que toca a argumentos "não posso utilizar X ou Y", sem uma razão específica de que não podes usar para praticar um pormenor, é completamente absurdo.

apresentar uma solução melhor usando novas ferramentas, demonstra capacidade de investigação e prática, o que são mais valias.

se o teu professor não entender isso, é porque precisas de um outro professor.

IRC : sim, é algo que ainda existe >> #p@p
Posted

Eu secalhar poder ate posso utilizar outras ferramentas, mas como este projecto é um projecto final de uma cadeira, vou ter de o explicar e defende-lo.. Como tive apenas 50h de programação não posso fazer nada muito complexo, porque ao utilizar funções mais complicadas o professor vai me questionar, porque e que meti aquela função ali, o que é que ela faz, etc.. E como eu estou a iniciar ainda na programação não vou ser capaz de me defender, por isso e que eu estou a tentar fazer o projecto com instruções que eu sei o que fazem e que me foram explicadas.

A parte da protecção secalhar até não é possivel fazer só com estas intruções que eu aprendi, mas como o programa é avaliado tambem nos bugs queria tentar proteger isto.

Este ciclo que me fizeste agora e para o colocar depois dos scanf()?

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.