IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

pb fonction date dans structure tm


Sujet :

C

  1. #1
    Membre habitué
    Inscrit en
    Novembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 12
    Par défaut pb fonction date dans structure tm
    Bonjour,
    J'ai réalisé une fontion qui découpe une date au format YYYY-MM-DDTHH:MM:SS.sss et range les éléments dans une structure tm. Cette fonction marche, elle est codée comme suit:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    struct tm *fDateT_To_Struct(char *strdate) {
     
     static struct tm returndate;
     sscanf(strdate,"%4d-%2d-%2dT%2d:%2d:%2d.%3d",&(returndate.tm_year)
    				             ,&(returndate.tm_mon)
    				             ,&(returndate.tm_mday)
    					,&(returndate.tm_hour)
    					,&(returndate.tm_min)
    				    	,&(returndate.tm_sec)
    				             ,&(returndate.tm_isdst));
    	returndate.tm_wday = 0;
      	returndate.tm_yday = 0;
     
    	return &returndate ;
    }
    Maintenant, je souhaite inclure un code de retour d'erreur RetCode à ma fonction. J'ai modifié ma fonction comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    RetCode fDateT_To_Struct(char *strdate, struct tm *st_dateStruct) {
     
    	RetCode retCode;
    	int i=0; 
    	static struct tm returndate;
     
    	i = sscanf(strdate,"%4d-%2d-%2dT%2d:%2d:%2d.%3d"
                                                                           ,&(returndate.tm_year)
    				                    ,&(returndate.tm_mon)
    				                    ,&(returndate.tm_mday)
    					       ,&(returndate.tm_hour)
    					       ,&(returndate.tm_min)
    				    	       ,&(returndate.tm_sec)
    				                   ,&(returndate.tm_isdst));
    	returndate.tm_wday = 0;
      	returndate.tm_yday = 0;
    	st_dateStruct = &returndate;
     
    	if (i<0) goto error;
    	else goto fin;
     
    error:
    	retCode = NOK;
    fin:
    	retCode = OK;
     
    return(retCode);
    }
    Mais lorsqu'un j'appelle ma fonction, cela ne marche plus!
    (bout de code du main

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct tm *pt_Str;
    char  carac[25]; 
    RetCode retcode; /*RetCode type prédéfini: accepte OK ou NOK*/
     
    strcpy(carac, "2002-11-03T23:45:01.556");
     
    retCode = fDateT_To_Struct(carac, pt_Str);
    printf("pt_Str-> tm_year: %d\n",pt_Str->tm_year); /*par exemple*/
    Il y a une erreur à l'exécution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    signal SEGV (no mapping at the fault address) in main at line 111 in file "mon_fichier.c"
      111                   printf("pt_Str-> tm_year: %d\n",pt_Str->tm_year);
    Je ne maîtrise pas bien les pointeurs de structure. Quelqu'un aurait-t-il une idée?
    Merci beaucoup
    Sandra

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut


    Moi, je ferais plutôt un truc dans ce genre-là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    RetCode fDateT_To_Struct(char const *sDate, struct tm *pDateStruct)
    {
    int i=0;
     
    /* Contrôle des paramètres */
    if(sDate==NULL || pDateStruct==NULL)
    	return NOK;
     
    i = sscanf(sDate,"%4d-%2d-%2dT%2d:%2d:%2d.%3d",
     &(pDateStruct->tm_year),
     &(pDateStruct->tm_mon),
     &(pDateStruct->tm_mday),
     &(pDateStruct->tm_hour),
     &(pDateStruct->tm_min),
     &(pDateStruct->tm_sec),
     &(pDateStruct->tm_isdst)
     );
    pDateStruct->tm_wday = 0;
    pDateStruct->tm_yday = 0;
     
    return ((i==7) ? OK : NOK);
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre habitué
    Inscrit en
    Novembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 12
    Par défaut
    Ah oui merci, j'y penserai la prochaine fois.
    J'ai testé ta solution, ça plante à l'exécution sur:

    signal SEGV (no mapping at the fault address) in number at 0xfea8c918
    0xfea8c918: number+0x085c: st %i1, [%o0]
    Current function is fDateT_To_Struct
    439 );

    Sandra

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Comment appelles-tu la fonction ?
    PS: J'ai oublié un test dans le contrôle des paramètres, je viens de le rajouter.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Par défaut
    Il me semble, que ta variable "pt_Str" de type "tm*" n'est jamais allouée... A moins que sscanf le fasse (mais j'en doute), il manque sans doute un "malloc" quelque part, non ?

  6. #6
    Membre habitué
    Inscrit en
    Novembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 12
    Par défaut
    Comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    RetCode retCode;
    struct tm *pt_Str;
    char date[25];
     
    strcpy(date, "2002-05-11T22:12:45.123");
     
    retCode = fDateT_To_Struct(date, pt_Str);		
    if (retCode != OK) {
    /*gestion d'erreur*/		
    }

    Sandra

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    C'est à dire, mal.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    RetCode retCode;
    struct tm Str;
    char date[25] = ""; /* ou char date[25]={0};*/
     
    strncpy(date, "2002-05-11T22:12:45.123", 25-1);
     
    retCode = fDateT_To_Struct(date, &Str);		
    if (retCode != OK) {
    /*gestion d'erreur*/		
    }
    Tu passais un pointeur non-initialisé à la fonction. Plantage pratiquement garanti, avec ou sans le test que j'avais oublié. Tu espérais que la fonction modifie le pointeur, alors que les variables sont passées par valeur en C ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Par défaut
    Citation Envoyé par Fabllot
    Il me semble, que ta variable "pt_Str" de type "tm*" n'est jamais allouée... A moins que sscanf le fasse (mais j'en doute), il manque sans doute un "malloc" quelque part, non ?
    Petite précision :
    Dans le code de Sandra, je ne suis pas sûr que cela soit très "propre", mais grâce à la déclaration d'une structure "static" ça doit fonctionner (du moins pas de problèmes mémoire ici)...

    Cependant, ma remarque concernait en fait la modification du code par Medinoc, qui du coup remplit une structure non allouée...

  9. #9
    Membre habitué
    Inscrit en
    Novembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 12
    Par défaut
    D'accord, je ne maitrise pas encore les pointeurs. Mais maintenant, j'ai le problème qui est reporté car utilisant une structure et non plus un pointeur de structure, je veux appeler un autre fonction qui à partir de la structure tm construit une date au format DD/MM/YYYY HH:MM:SS et les millisecondes.
    Mais celle-ci accepte un pointeur de struture en entrée!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    RetCode fDateT_To_Date(struct tm *Struct, char *Date, char *micro) 
    {
    RetCode		retCode;
    int 		i=0;
    int           	j=0;
     
    i = sprintf (Date , "%02d/%02d/%4d %02d:%02d:%02d", Struct->tm_mday,
    					           	Struct->tm_mon,
    						Struct->tm_year,
    						Struct->tm_hour,
    						Struct->tm_min,
    						 Struct->tm_sec);
    j = sprintf(micro, "%3d", Struct->tm_isdst);
     
    if ((i < 0) && (j < 0)) goto error;
    else goto fin;
     
    error:
    	retCode = NOK;
    fin:
    	retCode = OK;
     
    return(retCode);
    }
    Comment je fais pour l'appeler?
    Avant, je faisais comme ça (quand j'avais déclaré un pointeur de structure et non une structure...)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     
    retCode = fDateT_To_Date(pt_Str, Date, DateMs);
    if (retCode != OK) {
    /* gestion d'erreur */
    }
    Merci pour votre aide

  10. #10
    Membre habitué
    Inscrit en
    Novembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 12
    Par défaut
    J'ai trouvé! Je modifie ma fonction comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    RetCode fDateT_To_Date(struct tm Struct, char *Date, char *micro) 
    {
    RetCode		retCode;
    int 		i=0;
    int     	j=0;
     
    i = sprintf (Date , "%02d/%02d/%4d %02d:%02d:%02d", &(Struct.tm_mday),
    					           	&(Struct.tm_mon),
    					   	&(Struct.tm_year),
    					   	&(Struct.tm_hour),
    					   	&(Struct.tm_min),
    					   	&(Struct.tm_sec));
    j = sprintf(micro, "%3d", &(Struct.tm_isdst));
     
    if ((i < 0) && (j < 0)) goto error;
    else goto fin;
     
    error:
    	retCode = NOK;
    fin:
    	retCode = OK;
     
    return(retCode);
    }
    et je l'appelle comme avant.
    Merci pour toutes votre aide et remarques. Mais je sens que je ne maîtrise pas encore tout ça comme il faut.
    Auriez-vous une bonne référence de bouquin sur les pointeurs et structures?
    Sandra

  11. #11
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Par défaut
    Citation Envoyé par sandra771
    Auriez-vous une bonne référence de bouquin sur les pointeurs et structures?
    Sandra
    http://c.developpez.com/livres/#L2100490184

  12. #12
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Par défaut
    Il vaut mieux faire quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    RetCode fDateT_To_Date(struct tm *Struct, char *Date, char *micro) {
    [...]
    j = sprintf(micro, "%3d", Struct->tm_isdst);
    [...]
    }
    que ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    RetCode fDateT_To_Date(struct tm Struct, char *Date, char *micro) {
    [...]
    j = sprintf(micro, "%3d", &(Struct.tm_isdst));
    [...]
    }
    Dans le premier, tu passe un pointeur vers la structure, alors que dfans le second tu fais une copie de l'objet...
    Certes, dans le premier cas, il faut faire très attention aux déclarations / allocations / initialisations, mais c'est plus sûr...

  13. #13
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Fabllot
    Dans le code de Sandra, je ne suis pas sûr que cela soit très "propre", mais grâce à la déclaration d'une structure "static" ça doit fonctionner (du moins pas de problèmes mémoire ici)...

    Cependant, ma remarque concernait en fait la modification du code par Medinoc, qui du coup remplit une structure non allouée...
    Non, c'est crade. On écrit pas du code crade pour cause de "problèmes mémoire". On apprend à programmer et on écrit du code propre et utilisable partout, y compris avec des threads...

    Ne pas mélanger code et données. Jamais. Travailler par contexte. C'est toujours l'appelant qui est responsable de ses données, (en cas d'allocation dynamique dans la fonction, l'adresse est retournée à l'appelant qui en est responsable, de même que de la libération).

    La code de Medinoc est correct. C'est l'appel qui est faux. Le compilateur aurait pu le signaler...

Discussions similaires

  1. Utilisation de la fonction date dans une fonction
    Par Brebiou dans le forum Langage
    Réponses: 2
    Dernier message: 12/01/2015, 09h18
  2. [XL-2007] Problème fonction "DATE" dans "calendrier perpétuel"
    Par ATLONIA dans le forum Excel
    Réponses: 4
    Dernier message: 23/11/2014, 18h30
  3. Fonction Date() dans une table access
    Par Totik dans le forum Access
    Réponses: 5
    Dernier message: 04/10/2009, 21h20
  4. [MySQL] Envoi mail auto en fonction date dans base de donnée
    Par calitom dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 30/06/2008, 15h17
  5. Fonction date() dans valeur par défaut
    Par guiguikawa dans le forum Access
    Réponses: 2
    Dernier message: 15/06/2006, 15h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo