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 :

Ecriture d'une date


Sujet :

C

  1. #1
    Nouveau membre du Club
    Ecriture d'une date
    Bonjour,
    Dans le programme que je suis entrain de faire, je souhaiterai que l'utilisateur rentre une date (ex: 12/03/2020).
    Je voudrais donc que l'utilisateur est une interface comme ceci :
    .../.../... (apres avoir écrit 2 nombres passe dans le 2eme partie ...)
    J'ai donc pensé à faire :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    printf("Quel date : "); scanf("%d / %d / %d" , &date1 , &date2 , &date3);
    (avec date1,date2 et date 3 des entiers)
    Cependant, ca ne marchait pas .
    J'ai donc fait :
    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
     
     #include <stdlib.h>
     #include <stdio.h>
     #include <string.h>
     
     
     
     
    int main (){        
      	int date1 = 0, date2 = 0, date3 = 0;
        int mdate1 = 0, mdate2 = 0, mdate3 = 0;
        int date_finale = 0;
        ///// Date /////
        printf("Quel date : "); scanf("%d", &date1) ;  printf("/");scanf("%d", &date2);printf("/");scanf("%d", &date3);
        mdate1 = 1000000 * date1; mdate2 = 10000 * date2; mdate3 = date3;
        date_finale = mdate1 + mdate2 + mdate3;
        printf("Date : %d ", date_finale);
        return 0;
     
    }


    Cependant, le résultat n'est toujours pas la ...
    2 solutions s'offrent à moi :
    - Essayer d'enlever les retours à la ligne après les printf et les scanf. Puis modifier l'affichage de la date_final
    -Faire de la manière .../.../... (Mais je ne vois pas du tout comment faire)

    Voila, j'espère que c'est assez clair et que vous allez pouvoir m'aider
    @+
    Bapth

  2. #2
    Expert confirmé
    Bonjour,

    Malheureusement il n'existe aucune possibilité dans bibliothèque standard. Les entrées/sorties se font à partir de la console qui ne transmet les données qu'une fois la touche enter frappée. Et elle gère elle-même le défilement des lignes.

    Seule possibilité passer par des capacités spécifiques (qui en interne utilise des commandes spécifiques à chaque console.) Si tu précises dans quel environnement ton code s'exécute, il y a probablement des solutions plus ou moins simples.

  3. #3
    Nouveau membre du Club
    Merci pour ta réponse rapide,
    Je suis sous Windows et j'utilise Visual Studio Code
    @+

  4. #4
    Expert confirmé
    Je ne connais bien Linux, je pense que tu voir tutoriel ncurses.

  5. #5
    Expert éminent sénior
    Bonjour
    Citation Envoyé par bapth Voir le message
    J'ai donc pensé à faire :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    printf("Quel date : "); scanf("%d / %d / %d" , &date1 , &date2 , &date3);
    (avec date1,date2 et date 3 des entiers)
    Enlève les espaces. scanf() attend une entrée formatée aux petits oignons. Si tu saisis "03/11/2020", alors que la fonction attend "03 / 11 / 2020" elle ne saura pas le gérer. Cette fonction a probablement été codée par les URSSAF tellement elle t'envoie chier tout ce qui n'est pas dans les clous

    Pour le reste ce que tu demandes n'est pas possible (ou alors en faisant appel à des outils dédiés à la gestion de l'écran mais tu dois alors te plonger dans la doc de l'outil car il te faut tout programmer la détection clavier etc) car comme l'a dit dalfab, le programme ne reprend son action qu'après appui de la touche "return".
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  6. #6
    Nouveau membre du Club
    Comme c'est pas possible, j'ai donc élaboré un peu mon programme.
    Je vous le transmets

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
     
     
     
     
    int main (){        
        int jour = 0, mois = 0, annee = 0;
        int jour_modif = 1, mois_modif = 1, annee_modif = 0;
        int date_finale = 0;
        ///// Date /////
        printf("Quel date : \n"); 
        printf("Jour : "); scanf("%d", &jour);
     
        while (jour > 31){
     
          printf("Il y a 28 ou 29 ou 30 ou 31 jours dans 1 mois \n"); printf("Recommence \n");
          printf("Jour : "); scanf("%d", &jour);
        }
     
        printf("Mois : "); scanf("%d", &mois);
        while (mois > 12){
          printf("Il y a 12 mois dans une année \n Recommence ...\n");
          printf("Mois : "); scanf("%d", &mois);
        }
     
        if (jour == 31){      
     
          while(mois == 02 || mois == 04 || mois == 06 || mois == 9 || mois == 11){
            printf("Impossible il ne peut pas y avoir 31 jours dans ce mois \n Recommence .... \n");
            printf("Mois : "); scanf("%d", &mois);
          }
        }
        if (jour  == 30 || jour == 31){
     
          while(mois != 02){
            printf("Il y a maximum 29 jours dans le mois de février \n Recommencer ...\n"); 
            printf("Mois : "); scanf("%d", &mois);
          }
        }
     
      printf("Annee : "); scanf("%d", &annee);
     
      while (annee > 2021){
        printf("Euh pas trop vite... Recommence ... \n");
        printf("Annee : "); scanf("%d", &annee);
      }
     
      jour_modif = 1000000 * jour; mois_modif = 10000 * mois; annee_modif = annee;
      date_finale = jour_modif + mois_modif + annee_modif;
      printf("Date = %d/%d/%d\n", jour , mois , annee);
      //printf("Date : %d ", date_finale);
      return 0;
     
    }


    J'ai normalement bien respecter l'indentation
    Sinon je vais encore le modifier pour qu'il puisse classer les dates. J'essayerai de le transmettre bientôt.
    @+
    Bapth

  7. #7
    Expert éminent sénior
    Citation Envoyé par bapth Voir le message
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        printf("Jour : "); scanf("%d", &jour);
     
        while (jour > 31){
     
          printf("Il y a 28 ou 29 ou 30 ou 31 jours dans 1 mois \n"); printf("Recommence \n");
          printf("Jour : "); scanf("%d", &jour);
        }
    Code c :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while (1) {
        printf("Jour : "); scanf("%d", &jour);
        if (jour <= 31) break;
        printf("Il y a 28 ou 29 ou 30 ou 31 jours dans 1 mois \n"); printf("Recommence \n");
    }



    Citation Envoyé par bapth Voir le message
    J'ai normalement bien respecter l'indentation
    C'est à peu près vrai (parfois il y a 3 espaces, parfois 4). Perso je préfère les vraies tabulations car c'est plus facile pour compter (au lieu de compter 12 espaces on compte 3 tabulations) et surtout tout est calé à la même verticale... mais bon sur ce point je fais partie de la minorité (on conseille généralement les espaces car le nb d'espaces gérés par la tabulation est modifiable et donc un source bien tabulé sur un éditeur X pourra sortir anarchique sur l'éditeur Y) mais je préfère la facilité.

    Citation Envoyé par bapth Voir le message
    Sinon je vais encore le modifier pour qu'il puisse classer les dates. J'essayerai de le transmettre bientôt.
    Ok, t'as l'air motivé. Je vais donc te montrer la fonction qsort(). Elle peut classer absolument n'importe quoi de classable. Tout ce que tu as à faire c'est créer la fonction de comparaison capable de comparer deux "n'importe quoi". Cette fonction doit juste recevoir deux pointeurs sur deux "n'importe quoi", puis faire sa sauce pour comparer et ressortir au final
    • un nombre < 0 si le "n'importe quoi" de gauche est plus petit que le "n'importe quoi" de droite
    • un nombre > 0 si le "n'importe quoi" de gauche est plus grand que le "n'importe quoi" de droite
    • 0 si le "n'importe quoi" de gauche est égal au "n'importe quoi" de droite


    Un exemple
    Code c :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
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    // La fonction permettant de comparer (selon ma vision personnelle) deux mots
    int cmp_trucs(const void *t1, const void *t2) {
    	// La fonction va comparer chaque mot à partir de leur second caractère (le premier ne sera donc pas pris en compte dans la comparaison)
    	return strcmp(*(char**)t1+1, *(char**)t2+1);
    }
     
    int main() {
    	char *mots[]={"pierre", "paul", "jacques", "mathieu", "bartholomé", "judas", "et les autres...", NULL};
    	char **pt;
    	size_t i;
     
    	// Premier affichage de démo
    	fputs("Avant tri:\n", stdout);
    	for (pt=mots, i=1; *pt != NULL; pt++, i++)
    		printf("mot %lu: [%s]\n", i, *pt);
     
    	// Le tri
    	qsort(mots, 7, sizeof(char*), cmp_trucs);
     
    	// Affichage du tableau trié
    	fputs("Après tri:\n", stdout);
    	for (pt=mots, i=1; *pt != NULL; pt++, i++)
    		printf("mot %lu: [%s]\n", i, *pt);
    }


    Bon c'est vrai, la fonction de comparaison est la plus compliquée à créer. Ce qu'il faut savoir, c'est qu'elle reçoit l'adresse de chaque élément du tableau, adresse reçue dans un pointeur universel "void *".
    Mes éléments étant des strings (des char*), l'adresse d'un "char *" c'est un "char **". Donc j'indique par un cast que t1 et t2 doivent être vus comme des char** (ce qu'ils sont en réalité, car un cast permet de forcer le C à voir un truc tel qu'il est, pas à forcer un truc à être ce qu'il n'est pas). Ces "char**" (adresse de strings) sont ensuite déréférencés ("* de truc" signifie "déréférencement de truc") ce qui me donne des strings (en réalité les adresses de leur premier caractère), et en rajoutant 1 à ces adresses je me déplace sur le second caractère. Bref la fonction de comparaison telle que je l'ai définie ne compare mes strings qu'à partir de leur second caractère.
    Ensuite pour qsort() le reste est assez simple. On lui passe le tableau à trier (évident), le nb d'éléments du tableau (encore évident) et la taille d'un élément (ce qui lui permet, elle, de swapper un élément avec un autre quand il n'est pas à la bonne place) et en dernier l'adresse de la fonction servant à comparer (un nom de fonction sans parenthèse correspond à son adresse, car une fonction étant un code, ce code possède lui aussi une adresse en RAM, adresse alors utilisable comme toute autre).

    PS: tu remarqueras aussi le pointeur NULL placé en fin de tableau, qui, comme le '\0' d'une string, me permet de détecter quand il se termine à l'affichage. J'aurais créé une fonction de "comptage", elle aurait pu utiliser ce NULL et je n'aurais pas eu à passer "7" à qsort(), je lui passais le retour du comptage.
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  8. #8
    Membre averti
    Sur un autre aspect, celui de la validation des dates, le programme laissera passer des dates avec 31 jours pour des mois qui n'en comportent que 30, il vérifie pas si le mois de février doit, pour l'année donnée, comporter 28 ou 29 jours.

    Valider une date est compliqué, mais le C contient une fonction qui peut t'aider : mktime(), de la façon suivante :

    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
    #include <stdio.h>
    #include <time.h>
     
    int main(void) {
        time_t rawtime;
        struct tm * timeinfo;
     
        int year  = 2020;   
        int month = 11;     
        int day   = 31;     /* erreur, il y a 30 jours */
     
        time(&rawtime);
        timeinfo = localtime(&rawtime);
        timeinfo->tm_year = year - 1900;
        timeinfo->tm_mon = month - 1;
        timeinfo->tm_mday = day;
     
        time_t newtime = mktime(timeinfo);
        if (newtime == -1 || timeinfo->tm_year != year - 1900 
            || timeinfo->tm_mon != month - 1 || timeinfo->tm_mday != day) {
            printf("Erreur : la date est erronée\n");
        }
     
        return 0;
    }

  9. #9
    Nouveau membre du Club
    Merci pour vos réponse !
    J'essaye d'avancer le programme mais en ce moment j'ai un peu moins le temps ....
    @+

###raw>template_hook.ano_emploi###