Ir ao conteúdo
  • Cadastre-se

C Estou travado, não consigo arrumar


Trem_P3

Posts recomendados

Escreva um programa que receba no máximo 15 valores inteiros e imprima quantos são os valores divisíveis por 5.
Considere que o usuário encerra a sequência ao digitar o valor 0.

USANDO DO WHILE!!!!

 

meu codigo: 

#include <stdio.h>

int main (){
    int num, contagem;
    contagem = 0;

    printf ("Digite ate 15 numeros: ");
    do{
    	scanf ("%d", &num);
        

        if (num%5 == 0)
        {
        	contagem++;
        }
    } while (num != 0 || num > 15);

    printf ("\n\nA quantidade de valores divisiveis por 5 sao: %d", num);

    return 0;
}

 

Esta aparecendo a quantidade de valores divisiveis por 5 sao: 0

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Trem_P3    seu código corrigido poderia ser assim  :

#include <stdio.h>
int main ()
{
    int num, contagem=0,ret,total_mum=0;
    printf ("Digite ate 15 numeros: ");
    do
    {
        Label_1:
        ret = scanf ("%d", &num);     // rete recebe zero se scanf falhou
        if( ! num ) break;            // significa se num não for diferente de zero
        if( ret == 0 ) goto Label_1;  // esse goto está em desuso mas funciona assim mesmo
        if (num % 5 == 0)
        {
            contagem++;
        }
        total_num++;                  // conta a qtd de numeros inseridos
    } while (total_num < 15);
    printf ("\n\nA quantidade de valores divisiveis por 5 sao: %d", cntagem);
    printf("\n\n\n");
    return 0;
}

 

Link para o comentário
Compartilhar em outros sites

Em 24/06/2021 às 13:37, devair1010 disse:

seu código corrigido poderia ser assim  :

 :( Não, não poderia. Está errado. Compilou isso ao menos, @devair1010? Acho que não.

 

Eis o que acontece:

 

        int num, contagem=0,ret,total_mum=0;

 

  • Não declare mais de uma variável por linha. Não é uma boa economia. Só fica ruim de ler e aumenta a chance de erros.
  • Se tivesse declarado um a um teria mais chance de ter visto ANTES de compilar que digitou errado o nome da (única) variável que acrescentou: imagino que pretendia escrever total_num.
  • inicialize todas as variáveis. Não inicializou num e pro exemplo em Windows ela deve estar com 0xCCCCCCCC, ou no popular -858.993.460. 
  • scanf() não retorna zero quando "falhou", como escreveu:
     
        // ret recebe zero se scanf falhou
        ret = scanf("%d", &num);

    retorna -1. E o erro pode ser visto em errno como é o normal para todas essas funções. scanf() retorna um valor de zero até o total de especificadores a serem atendidos, com o número de valores que conseguiu ler.

Exemplo:
 

    int res = scanf("%d %d %s",...);

 

scanf() pode retornar -1 se der erro, ou 0, 1, 2 ou 3. Entenda que não ler nada não é um erro para scanf() --- cujo propósito é scan formatted input afinal, e por isso o nome  --- e se isso é um erro para um programa o programa deve tratar. Esse tipo de função é chamado parser e tenta consumir o que tem na entrada até satisfazer a especificação. É normal não ler tudo, ou mesmo não ler nada.

 

Do seu programa:

 

    do
    {
        Label_1:
          ret = scanf("%d", &num);
// rete recebe zero se scanf falhou
          if (!num) break;
// significa se num não for diferente de zero
          if (ret == 0) goto Label_1;
// esse goto está em desuso mas funciona assim mesmo
      
      // ...

 

Essa construção está errada.

  • como ret é usada apenas para receber o resultado de scanf() seria mais seguro declarar na mesma linha.
  • não pode usar o valor de num antes de saber se leu de fato algo. Se scanf() não ler nada, por exemplo se o usuário acabar digitando um w ao invés de 2, já que a w fica logo embaixo, scanf() vai retornar 0, mas o valor de num fica inalterado
    • Só que você testa num antes de testar ret e aí já era: num vai valer o que tinha antes, o último número lido. Ou -858.993.460 se for o primeiro, no Windows.
  • não deve comparar ret com zero e sim com 1. Está claro que pretende continuar lendo até ler algo, e isso quer dizer ret == 1
    • goto Label_1 não foi uma boa escolha. Trata-se de um loop simples. Um goto só deixa tudo muito confuso: trata-se de um loop do() com um teste no fim e no começo do loop tem um label e o programa pode voltar ali como se fosse um continue.
    • só que existe o comando continue. Porque não usou o simples, já que um continue voltaria para a primeira linha do loop, exatamente onde colocou o label?

Exemplo:
 

    do
    {
        int ret = scanf("%d", &num);
// rete recebe zero se scanf falhou
        if (!num) break;
// significa se num não for diferente de zero
        if (ret != 1) continue; 
      
      // ...

 

Ainda está errado. Só estou mostrando que o continue seria uma opção mais clara.

 

Uma outra opção, mais legível, seria usar um while ou um do no scanf(), já que o programa quer chamar scanf() até ler algo, e esse é exatamente o comportamento do comando do: fazer algo até uma condição ser satisfeita.

 

E claro que tem que testar o retorno ANTES de usar o valor de num porque se scanf() não ler nada vai usar o valor anterior de num no if. Quanto ao if(), evite usar operadores lógicos se está testando valores decimais. Em especial em programas para estudantes. 
 

    if ( ! num ) ///...

 

Na verdade quer testar se num vale zero porque essa é uma condição de saída do programa. O fato de em C zero ser falso quer dizer que !num é a mesma coisa que (num == 0) mas para um iniciante lendo isso ou para uma melhor leitura  a segunda opção é bem mais clara.

 

E seria interessante mostrar qual número está lendo, do total de 15 possíveis. Uma opcional cortesia ao usuário, já que é um p0rr3 ficar contando os 15, mesmo que seja você testando seu próprio programa.

 

        if (num % 5 == 0)
        {
            contagem++;
        }

 

Essas chaves não são necessárias e não ajudam a ler o comando. E como a contagem é de múltiplos talvez multiplos fosse um nome melhor para essa variável...
 

        if (num % 5 == 0) multiplos += 1;

 

seria mais expressivo.

 

Um possível programa

 

#include <stdio.h>
int main(void)
{
    int     a_ler = 1;
    int     multiplos = 0;
    int     total_num = 3;

    printf("Digite ate %d numeros\n\n", total_num);
    do
    {
        int num = 0;
        printf("[%d de %d] Numero: ", a_ler, total_num);
        if (1 != scanf("%d", &num)) break; // aborta se não leu
        if ( num == 0 ) break; // 0 indica fim
        if (num % 5 == 0) multiplos += 1;
        a_ler += 1; // conta o lido

    }   while (a_ler <= total_num);
    printf("\nLidos %d numeros, %d sao multiplos de 5\n",
           a_ler-1, multiplos);
    return 0;
}

 

E fica mais fácil de entender o que acontece:

Clube>  ./dvr
Digite ate 3 numeros

[1 de 3] Numero: x

Lidos 0 numeros, 0 sao multiplos de 5
Clube>  ./dvr
Digite ate 3 numeros

[1 de 3] Numero: 5
[2 de 3] Numero: 0

Lidos 1 numeros, 1 sao multiplos de 5
Clube>  ./dvr
Digite ate 3 numeros

[1 de 3] Numero: 5
[2 de 3] Numero: 5
[3 de 3] Numero: 5

Lidos 3 numeros, 3 sao multiplos de 5
Clube> 

 

De seu programa, @devair1010
 

    printf ("\n\nA quantidade de valores divisiveis por 5 sao: %d", cntagem);

 

Não compila: contagem era o nome da variável. E quantidade é singular.

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...