Ir ao conteúdo

Posts recomendados

Postado

Galera, tenho que colocar um código pra transformar horas, minutos e segundos em uma quantidade total de segundos, exemplos entrada:

5 12 1

Saída

O TEMPO EM SEGUNDOS E = 18721

Porém, quero fazer isso com função e sou iniciante com funções, sabem me dizer o que está dando errado com esse código ?

 

#include <stdio.h>
#include <math.h>
void converteTempo(int h, int m, int s){
    int tempo=h*3600;
    tempo+=m*60;
    tempo+=s;
    printf("O TEMPO EM SEGUNDOS E = %d\n", tempo);
}
int main()
{
    int h, m, s;
    void converteTempo(void);
    scanf("%d %d %d", &h, &m, &s);
    converteTempo();
    return 0;
}


 

Postado

Tem que passar os argumentos na chamada da função que no caso está em main.

 

Retire void converteTempo(void);. Use o que está abaixo de scanf.

  • Curtir 1
Postado
#include <stdio.h>
#include <math.h>

void converteTempo(void); //Definição do protótipo da função tem que ficar fora da MAIN e de outras funções, de preferência no começo do código

void converteTempo(int h, int m, int s)
{
    int tempo=h*3600;
    tempo+=m*60;
    tempo+=s;
    printf("O TEMPO EM SEGUNDOS E = %d\n", tempo);
}

int main()
{
    int h, m, s;

    scanf("%d %d %d", &h, &m, &s);
    converteTempo(h, m, s); // A função estava sem argumentos
    return 0;
}

 

Postado

@CiroboyBR Olá. Apenas um ponto que seria importante frisar: O protótipo de função poderia se assim:

void converteTempo(int, int, int); // protótipo da função, ela recebe três parâmetros

Desculpa ter que falar assim, mas creio que é preciso para um melhor aprendizado do autor do tópico :thumbsup:

  • Membro VIP
Postado

Olá.

 

Vou tentar complementar. Vamos lá:

 

 

 

1#

Sobre:

Em 25/09/2018 às 22:42, CiroboyBR disse:

void converteTempo(void);

 

Aqui no Dev-Cpp 5.11 TDM-GCC 4.9.2 com esse protótipo não funcionou. Mas com esse sim.

 

16 horas atrás, giu_d disse:

void converteTempo(int, int, int);

 

 

 

2#
Independente das formas dos protótipos que funcionam nos compiladores, se a função está em cima, não precisa do protótipo, já que o compilador já conhecerá a função. Poderia ficar com algo assim:

#include <stdio.h>
#include <math.h>
void converteTempo(int h, int m, int s) //aqui o programa já terá aprendido essa função
{
    int tempo=h*3600;
    tempo+=m*60;
    tempo+=s;
    printf("O TEMPO EM SEGUNDOS E = %d\n", tempo);
}

int main()
{
    int h, m, s;

    scanf("%d %d %d", &h, &m, &s);
    converteTempo(h, m, s); //vai utilizar a função que já aprendeu lá em cima
}
   

 

 

 

3#

O protótipo se faria necessário se a função estivesse abaixo da função que está lhe invocando, pois o compilador aprende de cima para baixo. Logo, se fazendo necessário algo para indicar que a função existe, ex.:

#include <stdio.h>
#include <math.h>

int main()
{
    int h, m, s;

    scanf("%d %d %d", &h, &m, &s);
    void converteTempo(int h, int m, int s); //o protótipo deve fica em qualquer lugar ANTES de ser invocado
    converteTempo(h, m, s); //o protótipo acima fará a função ser reconhecida
}

void converteTempo(int h, int m, int s) //como está em baixo, a função acima não "enxerga" essa função, daí
                                        //necessita do protópito 
{
    int tempo=h*3600;
    tempo+=m*60;
    tempo+=s;
    printf("O TEMPO EM SEGUNDOS E = %d\n", tempo);
}

ou poderia ficar assim:

    void converteTempo(int, int, int);
    converteTempo(h, s, m); // A função estava sem argumentos

Ou seja, a questão central aqui é que o protótipo só seria necessário se a função, que precisa da função correspondente, ainda não conheça ela.

 

 

Caso existam mais funções, que estão acima da função que precisa, seria necessário declarar o protótipo em cada uma delas!!! (lembrando que se  a função que precisa estiver abaixo, não precisará do protótipo).

 

OU

 

Declararia o protótipo FORA das funções, mas em algum lugar que está acima das funções que vão precisar.

 

RESUMINDO:

Uma função só poderá utilizar se:

  • a função estiver de algum modo antes da função que vai usar;
  • se um protótipo for declarado antes. Sendo que o protótipo poderá ser declara dentro da própria função que vai invocar a outra função (escopo local) E/OU ser declarado fora de funções (solto no código) antes da função que for usar (escopo global).

 

 

4#

Creio que a nomenclatura dessa função converteTempo() não está muito adequada, pois a principal utilidade dela não está na conversão, mas sim em exibir o tempo em segundos. Nesse sentido, uma nomenclatura mais justa seria exibeTempo(), ou seja, converter o tempo em segundos está só como uma etapa para exibir o tempo... não como o foco da função.

 

 

 

5#

Um exemplo que o "termo" converter me pareceria mais coerente, seria assim:

#include <stdio.h>
#include <math.h>

int main()
{
    int h, m, s;

    scanf("%d %d %d", &h, &m, &s);
    int converteTempo(int, int, int);
    printf("O TEMPO EM SEGUNDOS E = %d\n",converteTempo(h,m,s));
}

int converteTempo(int h, int m, int s)
{
    int tempo=h*3600;
    tempo+=m*60;
    tempo+=s;
    return tempo;
}

Ou seja, nesse caso, de fato a funcionalidade principal da função é converter o tempo. Esse tempo convertido e retornado pela própria função. E a exibição sendo feita em outro local.

 

 

***

 

O que acham em relação a cada item?

 

No aguardo.

Postado

É, fiz o comentário acima e apenas foquei na parte do protótipo da função sem considerar a lógica do código

Gostei da ideia dada pelo @Simon Viegas de definir a função com o tipo de retorno como int

Sobre protótipo de funções, o que eu poderia frisar é que bons programadores sempre declaram os protótipos das funções

Dessa forma, caso mais programadores trabalhem no mesmo código, já vão ter todas as características da função, como tipo de retorno, nome, quantidade de parâmetros e tipo de cada parâmetro

Seguindo a lógica apresentada acima, daria para deixar o código dessa forma:

#include <stdio.h>

int converte_tempo(int, int, int);

int main()
{
    int hora, min, seg, total_seg;

    printf("Digite um horario no formato HH:MM:SS -> ");
    scanf("%d%*c%d%*c%d", &hora, &min, &seg);

    total_seg = converte_tempo(hora, min, seg);

    printf("O TEMPO EM SEGUNDOS E = %d\n", total_seg);
}

int converte_tempo(int hora, int minuto, int segundo)
{
    int tempo = hora * 3600;
    tempo += minuto * 60;
    tempo += segundo;

    return tempo;
}

Obs: do modo como está o código, um horário deve ser digitado como é solicitado. Ex: 02:35:40

  • Membro VIP
Postado

Sobre:

1 hora atrás, giu_d disse:

    printf("Digite um horario no formato HH:MM:SS -> ");
    scanf("%d%*c%d%*c%d", &hora, &min, &seg);

 

Poderia explicar como isso funciona? suponho que o c é para de alguma forma "tirar os ':'". Esse "*" é para não precisar de uma variável?

 

Pelo que testei aqui, uma forma menos elegante seria algo assim:

    printf("Digite um horario no formato HH:MM:SS -> ");
    scanf("%d%c%d%c%d", &hora,&str,&min,&str,&seg);

Correto?

 

 

 

Sobre:

1 hora atrás, giu_d disse:

Ex: 02:35:40

Não precisa desse 0 antes. E pelo que eu vi, poderá escreve qualquer coisa seja "número+caractere+número+caractere+número". Inclusive com espaços espaços ou ENTER. Ex.:
 

Digite um horario no formato HH:MM:SS -> 1
1
1
O TEMPO EM SEGUNDOS E = 3661

ou

Digite um horario no formato HH:MM:SS -> 1 1 1
O TEMPO EM SEGUNDOS E = 3661

 

 

Postado

@Simon Viegas

7 horas atrás, Simon Viegas disse:

Poderia explicar como isso funciona? suponho que o c é para de alguma forma "tirar os ':'". Esse "*" é para não precisar de uma variável?

Olá. Seria algo assim mesmo 

Quando eu faço %c é para ler um caractere e armazenar em uma variável, mas quando faço %*c é para ler um caractere (no caso os dois pontos ':' ou qualquer outro caractere digitado) e descartar 

Simplesmente lê um caractere e descarta o mesmo :thumbsup:

Um uso muito bom desse recurso em C é para limpar a sujeira no buffer (stdin) que o Sr. chama de "bug do scanf",  com uma função como essa:

void limpa_linha() {
    scanf("%*[^\n]");
    scanf("%*c");
}

No caso dessa função, a primeira diretiva %*[^\n] lê quaisquer valor ordinário (sujeira no buffer) e descarta esses valores, exceto o '\n' (quebra de linha)

No segundo scanf tem a diretiva %*c, que é para ler o caractere '\n' (quebra de linha) e descarta o mesmo também, limpando de maneira adequada o stdin e evitando que as seguintes leituras do teclado de um código sejam afetadas com qualquer sujeira no buffer

  • 4 anos depois...
Postado

Ola pessoal sou novo nessa area mas criei essa logica aqui achei mais simples do que a forma que vcs estavam falando ali em cima , mas ja adianto de ante mão que sou novo nisso então se puderem comentar o que acham ai dessa logica e se faz sentido e da certo também, eu agradeceria muito , pois isso me ajudaria a aumentar meus conhecimentos, valeu muito obrigado...

 

#include <stdio.h>
#include<math.h>

int main() {
   int hora, minuto, segundo,total_minutos;
  
   printf("Informe a hora, no formato HH:MM:SS\n");
   scanf("%d%*c%d%*c%d",&hora,&minuto,&segundo);
   printf("\n");
   total_minutos = hora*60+minuto+segundo/60;
   printf("Ja se passaram %d minutos e %d segundos\n\n",total_minutos,segundo);
   printf("ou\n\n");
  printf("Ja se passaram no total %d segundos \n ",(hora*3600)+(minuto*60)+segundo);
}
 

Postado

Use o botão code como explicado no primeiro post do forum.

 

Veja a diferença:
 

#include <stdio.h>
#include <math.h>

int main()
{
    int hora, minuto, segundo, total_minutos;

    printf("Informe a hora, no formato HH:MM:SS\n");
    scanf("%d%*c%d%*c%d", &hora, &minuto, &segundo);
    printf("\n");
    total_minutos = hora * 60 + minuto + segundo / 60;
    printf(
        "Ja se passaram %d minutos e %d segundos\n\n",
        total_minutos, segundo);
    printf("ou\n\n");
    printf(
        "Ja se passaram no total %d segundos \n ",
        (hora * 3600) + (minuto * 60) + segundo);
}

 

3 horas atrás, igor alexandre senenko disse:

mais simples do que a forma que vcs estavam falando ali em cima , mas ja adianto de ante mão que sou novo nisso então se puderem comentar o que acham ai dessa logica e se faz sentido e da certo também

 

Parece certo e mais simples, quatro anos depois. Mas acho que não está bom ainda:

  • Porque razão tirou a função da questão original? Todo o sentido de C está nas funções.
  • TESTE sempre o retorno de scanf(). É ingênuo seguir adiante sem testar.
  • declare uma variável por linha. Vai gostar disso quando seus programas tiverem centenas de linhas ao invés de 20. E é grátis.
  • inicialize todas as variáveis.
  • main() retorna um int. Use um return. É boa prática. Nem todos seus programas vão ter uma função só.
  • Se não tem argumentos use void. Assim deixa claro para você e pros outros que não esqueceu de por os argumentos.
  • Ao perguntar algo deixe o cursor na MESMA LINHA da pergunta. O usuário sempre espera o prompt na mesma linha da resposta. Teste.
  • Se já informou o formato não seria o caso de reforçar o mesmo? scanf() foi escrita para isso. Use algo como
     
        unsigned hh = 0;
        unsigned mm = 0;
        unsigned ss = 0;
        const char* mask = "%2u:%2u:%2u";
    
        printf("Informe a hora, no formato HH:MM:SS (2 digitos para cada valor): ");
        int res = scanf( mask, &hh, &mm, &ss);
        if (res != 3)
        {
            printf("Erro na entrada\n");
            return -1;
        }

     

           Isso torna sua vida mais fácil: é mais fácil o cara digitar tudo certinho como "02:34:55" e a função já controla pra você. scanf() é um scanner. Foi escrita para isso: scan formatted input. E se ele não digitar assim o programa mostra uma mensagem e encerra. O simples. E limitando a dois digitos não vai estourar o que cabe em um int se o cara digitar uns números gigantes só pra ver se você pensou nisso.

  • Pela mesma razão use unsigned para os valores que não podem ser negativos e assim você se defende do chato ou do professor que testou com um valor negativo só pra ver se você pensou nisso.
  • em valores que vai usar para contas e operar use nomes pequenos. A própria questão já sugere algo como hh mm e ss. É chato ficar digitando nomes grandes em expressões.

EXEMPLO

 

#include <stdio.h>
#include <math.h>

unsigned tempo_em_s(unsigned, unsigned, unsigned);

int main(void)
{
    unsigned hh = 0;
    unsigned mm = 0;
    unsigned ss = 0;
    const char* mask = "%2u:%2u:%2u";

    printf("Informe a hora, no formato HH:MM:SS (2 digitos para cada valor): ");
    int res = scanf( mask, &hh, &mm, &ss);
    if (res != 3)
    {
        printf("Erro na entrada\n");
        return -1;
    }
    printf(
        "%02u:%02u:%02u = %us\n",
        hh, mm, ss,
        tempo_em_s(hh,mm,ss)
    );
    return 0;
}

unsigned tempo_em_s(unsigned hh, unsigned mm, unsigned ss)
{
    return ss + mm * 60 + hh * 3600;
}

 

Sobre a discussão de 2018

 

Em 27/09/2018 às 11:23, Simon Viegas disse:

Independente das formas dos protótipos que funcionam nos compiladores, se a função está em cima, não precisa do protótipo, já que o compilador já conhecerá a função

 

Assim é. Mas não deve colocar as funções antes de main. Nunca. As razões:

  • o programa começa em main() então ao abrir o programa sempre se espera ver o código de main logo no início. Em especial se vai postar isso num forum ou se trabalha com mais alguém. Depois de um tempo se voltar ao programa você mesmo vai odiar ter que ficar procurando por main para entender o programa. Em geral os programas não são escritos para esquecer assim que funcionam. Eles continuam sendo usados e mantidos.
  • as declarações de protótipos e estruturas em geral vão para outro arquivo ou outros arquivos do tipo .h, para se poder usar o mesmo código em vários programas. Essa é a razão de escrever código afinal. Essa função que converte hh:mm:ss em segundos vai para um arquivo .h como vai o printf() por exemplo. E no futuro para usar se usa um #include como no caso de stdio.h por exemplo. E não se compila mais esse código, como não se compila mais um printf ou scanf.
Em 27/09/2018 às 12:10, Visitante disse:
printf("Digite um horario no formato HH:MM:SS -> ");
    scanf("%d%*c%d%*c%d", &hora, &min, &seg);

 

Evite a todo custo ler letras em scanf() com '%c'. Isso sempre dá problema. E evite o '*' que simplesmente descarta o valor obtido pelo especificador. Isso porque o usuário pode digitar muitas letras e não uma só. E tem o lance dos tabs e newlines e espaços que scanf vai pular de todo modo. Se tem a possibilidade de ler algo já formatado como hh:mm:ss USE isso e coloque os ':' na máscara, como
 

    const char* mask = "%2u:%2u:%2u";

 

assim scanf() controla isso pra você. Se retornar 3 é porque leu os 3 valores positivos e com no máximo 2 dígitos cada um... 😉  e você não precisou fazer nada.

 

Em 27/09/2018 às 13:43, Simon Viegas disse:

Poderia explicar como isso funciona? suponho que o c é para de alguma forma "tirar os ':'". Esse "*" é para não precisar de uma variável?

 

Exato. scanf() foi escrita para ler dados tabulares, tabelas a partir de arquivos. Coisas como arquivos CSV nos anos 70. Se você tem um arquivo com dados como região, população, renda média, idade média e nível escolar por exemplo e em um programa precisa apenas da população e da idade e nível escolar pode usar "%*s" para ignorar os campos que não vai usar. Fica tudo mais simples.

 

Em 27/09/2018 às 13:43, Simon Viegas disse:

Não precisa desse 0 antes. E pelo que eu vi, poderá escreve qualquer coisa seja "número+caractere+número+caractere+número". Inclusive com espaços espaços ou ENTER.

 

Por isso é melhor usar algo como "%2u:%2u:%2u" e deixar a função scanf controlar a entrada de dados usando os ':' no lugar esperado.

 

Em 27/09/2018 às 21:12, Visitante disse:

Um uso muito bom desse recurso em C é para limpar a sujeira no buffer (stdin) que o Sr. chama de "bug do scanf", 

 

Não existe "sujeira do buffer" e scanf() não tem esse "bug". Apenas é ensinado errado o uso e scanf é usada para fins diversos daqueles para a qual foi escrita. E também aparentemente não é ensinado que o teclado existe como algo compartilhado por vários programas e funções e o que se digita não é nunca simplesmente lixo. Não existe lixo de teclado. Apenas existem programas mal construídos que não entendem o que é a entrada padrão e o fato de a entrada padrão por definição sempre esperar por um ENTER para enviar os dados para um programa.

 

O sistema não tem como saber se os dados que vem a seguir são para o programa ou são pra outra função ou se um gato está andando sobre as teclas. 

 

Por isso qualquer programa sério que precisa ler do teclado desabilita o eco do que foi digitado e a espera pelo ENTER e lê as teclas uma a uma e testa pra ver se está dentro do esperado e só aí mostra na tela. Assim um formul;ario por exemplo aceita só números e coloca os pontos para separar os milhares e ignora as letras sem zoar a tela e tal: código. 

 

Em 27/09/2018 às 21:12, Visitante disse:

No caso dessa função, a primeira diretiva %*[^\n] lê quaisquer valor ordinário (sujeira no buffer) e descarta esses valores, exceto o '\n' (quebra de linha)

No segundo scanf tem a diretiva %*c, que é para ler o caractere '\n' (quebra de linha) e descarta o mesmo também, limpando de maneira adequada o stdin e evitando que as seguintes leituras do teclado de um código sejam afetadas com qualquer sujeira no buffer

 

Pois é: o mito da sujeira do buffer. 

 

  • Obrigado 1

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!