Heures, minutes, secondes...

Résolu/Fermé
Signaler
-
Messages postés
5672
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 novembre 2021
-
Bonsoir,

J'ai un petit problème en C. Je souhaite que mon programme renvoie, à partir des secondes entrées par l'utilisateur, l'équivalent en jours, heures, minutes, secondes.
Tout fonctionne, sauf dans certains cas. Par exemple, lorsque j'entre
6849684141698168161
en secondes, j'obtiens
-23001 jours, -12 heures, -52 minutes et -47 secondes

Ou lorsque j'entre
100000000000000000000000000000000000000000
secondes, j'obtiens des 0 jours, 0 heures, 0 minutes, 0 secondes...
Alors que par exemple avec
7445622
j'obtiens bien
8 jours, 14 heures, 49 minutes et 22 secondes
.
Le problème viendrait-il de la capacité de stockage de long int ?

Voici le code :

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

void clock(int* jours, int* heures, int* minutes, int* secondes);

int main(int argc, char *argv[])
{
    long int jours = 0, heures = 0, minutes = 0, secondes;
    scanf("%d", &secondes);

    clock(&jours, &heures, &minutes, &secondes);

    printf("%d jours, %d heures, %d minutes et %d secondes",jours ,heures, minutes, secondes);

    return 0;
}

void clock(int* jours, int* heures, int* minutes, int* secondes)
{
    *jours = (*secondes/3600)/24;
    *heures = *secondes / 3600;
    *minutes = *secondes / 60;
    *secondes = *secondes % 60;
    *minutes = *minutes % 60;
    *heures = *heures % 24;
}


Merci.
<\EchoIsON>
.

4 réponses

Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 797
Bonjour,

Attention à la cohérence entre les types :
void clock(int* jours, int* heures, int* minutes, int* secondes);
Tu appelles cette fonction avec des long. Il est possible que cela ne change rien sur ta machine (int = long int sur certaines plateformes), mais ce n'est pas bon pour autant.

Sinon, les valeurs que tu as entrées sont trop grandes pour être contenues dans un long. Tu peux essayer avec long long (C90) si tu souhaites plus de place. Mais, ça restera limité...
Tu veux vraiment rentrer des valeurs aussi grandes ? Si oui, il va te falloir implémenter une bibliothèque type BIGNUM.
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 41989 internautes nous ont dit merci ce mois-ci

Messages postés
5672
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 novembre 2021
955
Salut EchoIsON,

Juste une remarque, qui ne répond pas à ta question mais qui concerne le nommage de ta fonction.

clock()
est une fonction standard du C accessible par time.h et qui fait tout autre chose.

http://www.cplusplus.com/reference/ctime/clock/

Pour cette raison, je pense que tu devrais éviter d'appeler ta fonction "clock()".


Dal
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 41989 internautes nous ont dit merci ce mois-ci

Merci à tous, [Dal] je prend en compte le conseil.

En effet il y a une incohérence avec long int et int dans la fonction mais le problème était toujours présent même avant que je change int en long int.
fiddy, est-ce-que je pourrais avoir plus de précisions sur la bibliothèque BIGNUM, svp ?

Voici le code modifié :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void heure(long int* siecles, long int* annees, long int* mois, long int* jours, long int* heures, long int* minutes, long int* secondes);

int main(int argc, char *argv[])
{
    long int siecles = 0, annees = 0, mois = 0, jours = 0, heures = 0, minutes = 0, secondes;
    scanf("%d", &secondes);

    heure(&siecles, &annees, &mois, &jours, &heures, &minutes, &secondes);

    printf("%d siecles, %d ans, %d mois, %d jours, %d heures, %d minutes et %d secondes", siecles, annees, mois, jours ,heures, minutes, secondes);

    return 0;
}

void heure(long int* siecles, long int* annees, long int* mois, long int* jours, long int* heures, long int* minutes, long int* secondes)
{
    *siecles = ((((*secondes/3600)/24)/30)/12)/100;
    *annees = (((*secondes/3600)/24)/30)/12;
    *mois = ((*secondes/3600)/24)/30;
    *jours = (*secondes/3600)/24;
    *heures = *secondes / 3600;
    *minutes = *secondes / 60;
    *secondes = *secondes % 60;
    *minutes = *minutes % 60;
    *heures = *heures % 24;
    *jours = *jours % 30;
    *mois = *mois % 12;
    *annees = *annees % 100;
}
/* J'ai rajouté certaines modifications entre temps...*/


EDIT : J'ai rajouté unsigned lont int, je pense que cela m'offre une solution partielle... Au moins je n'ai plus de valeurs négatives.

Merci, EchoIsON.
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 797 > Utilisateur anonyme
Oui long long = long long int.
Note, as-tu bien changé les formats ? Par exemple dans les scanf() c'est %lld, etc.
N'hésite pas à montrer ton code avec les long long, si tu souhaites qu'on jette un coup d'oeil.
Messages postés
14828
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
18 novembre 2021
310
Juste une remarque dans :
scanf("%d", &secondes);
ce ne serait pas %ld plutôt ?
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 797 >
Messages postés
14828
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
18 novembre 2021

Oui. Bien vu :-).
Utilisateur anonyme
C'est parfait !

En entrant :
1000000000000000000000000000000000000000000000000000000000 
secondes
J'obtiens :
1714333191 siecles, 48 ans, 10 mois, 15 jours, 16 heures, 27 minutes et 44 secon
des

Donc tout semble fonctionner, et les long long marchent très bien !
Merci à tous.
Messages postés
5672
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 novembre 2021
955
Salut EchoIsON,

Tu devrais vérifier si tu peux stocker des nombres pareils sur ton implémentation.

En utilisant C99 tu as accès au type
long long int
et donc à
unsigned long long int
qui est approprié pour des secondes où tu n'as pas besoin d'entiers négatifs.

Note que la valeur maximale
unsigned long long int
pour ton implémentation est accessible par la macro ULLONG_MAX définie dans l'entête limits.h

http://www.cplusplus.com/reference/climits/

Un programme devrait documenter pour l'utilisateur les limites qu'il peut utiliser sans générer d'erreurs et l'en informer d'une façon ou d'une autre, et gérer les dépassements de capacité.

Par exemple en récupérant le nombre de secondes sous la forme d'une chaîne C (suffisamment dimensionnée) et en contrôlant le résultat de la saisie et de sa conversion avec strtoull() et errno (errno.h).


Dal
Messages postés
14828
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
18 novembre 2021
310
long int jours = 0, heures = 0, minutes = 0, secondes;
void clock(int* jours, int* heures, int* minutes, int* secondes)

Ce ne serait pas un problème de type ?