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 :

fonction void my_putNbr(int nombre) et utilisation de write


Sujet :

C

  1. #1
    Membre à l'essai
    Femme Profil pro
    Reconversion professionnelle en web développeur
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Reconversion professionnelle en web développeur

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Points : 11
    Points
    11
    Par défaut fonction void my_putNbr(int nombre) et utilisation de write
    Bonjour,

    Je débute en programmation et ai commencé par le Langage C. Je débute également sur ce forum... Je vous remercie d'avance de votre indulgence.

    Mon problème: j'essaie de créer une fonction de type void qui prend en paramètre un nombre et qui l'affiche avec la fonction write. Je bloque là dessus. J'avoue que je ne maîtrise pas la fonction write car j'ai appris l'affichage en C avec printf, fprintf. C'est dans des exercices que j'ai découvert write().

    Des lignes de code sans explication ne me seront d'aucune aide, je souhaite comprendre.

    Vos retours sont les bienvenus. Voilà mon code dont l'output est une boucle presque infinie du signe - (moins) qui s'achève par un Segmentation fault (core dumped):

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    void my_putNbr(int nombre);
    void my_putchar(char c);
     
    int main(int argc, char *argv[])
    {
      my_putNbr(-3);
     
      return 0;
    }
     
     
    void my_putNbr(int nombre)
    {
      if (nombre < 0)
      {
        my_putchar('-');
        my_putchar(nombre + 48); // 48 est la valeur Ascii de 0 (zéro)
      }
      else
      {
        my_putchar(nombre + 48);
      }
    }
     
    void my_putchar(char c)
    {
      write(1, &c, 1);
    }
    Merci de votre aide

  2. #2
    Membre éclairé Avatar de Bayard
    Inscrit en
    Juin 2002
    Messages
    859
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 859
    Points : 714
    Points
    714
    Par défaut
    Bonjour

    http://manpagesfr.free.fr/man/man2/write.2.html

    write permet d'écrire dans un fichier.

    la fonction write s'utilise aprés avoir utilisé la fonction open()
    http://manpagesfr.free.fr/man/man2/open.2.html

    le premier paramètre de la fonction write est un "File Descripter" : un numéro de fichier.
    Est-ce que tu savais cela en mettant un 1 ?

    https://www.geeksforgeeks.org/input-...se-read-write/

    remarque: il faudra également appeler close() quand tout les write auront été faits.

    Bonne journée !
    Si tu ne vis pas ce que tu penses alors tu penses ce que tu vis.

  3. #3
    Membre à l'essai
    Femme Profil pro
    Reconversion professionnelle en web développeur
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Reconversion professionnelle en web développeur

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Points : 11
    Points
    11
    Par défaut
    Merci Bayard de votre retour.

    Je savais que le 1er paramètre du write correspond au "file descriptor" qui pensais-je est par défaut le 1 c'est à dire la sortie sur l'écran. Je ne savais pas qu'il y a en fait 2 autres valeurs éventuelles. Votre lien geeksforgeeks m'a éclairé là-dessus entre autres.

    J'ai regardé vos liens qui renseignent bien sur la fonction write mais qui sauf erreur de ma part ne me permettent pas d'avancer sur mon problème. Peut-être que je me suis mal exprimée sur ce qui m'embête. Ma fonction my_putNbr, quand je l'écris avec un printf, me retourne bien le nombre passé en paramètre. Je souhaite avoir le même résultat en passant par my_putchar() qui fait appel à write().

    Quelle est l'approche ou le raisonnement à avoir?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par PetitPanda9 Voir le message
    Quelle est l'approche ou le raisonnement à avoir?
    C'est le problème du noob niveau 0

    Il y a une différence entre le chiffre (0, 1, 2, ... 9) et un caractère ASCII ('0', '1', '2', ... '9').
    La fonction printf transforme ton chiffre/ ton nombre en chaîne de caractères (format %d, %u, %f et petits frères).

    Il faut faire cette conversion : dans la table ASCII, la plage des numéros, des lettres (minuscules et majuscules) sont dans l'ordre.
    Donc la conversion chiffre <-> caractère est simple character = d + '0' (avec d: 0, 1, 2, ... 9) ou numeral = c - '0' (avec c: '0', '1', '2', ... '9').
    Pour la conversion (attention au sens ) :
    • nombre entier en chaîne de caractères, il faut faire des divisions / 10, avec le modulo pour avoir le chiffre - 125 -> 125 / 10 * 10 = 120, 125 - 120 = 5. Et en recommence tant que (nombre / 10) > 9.
    • chaîne de caractères en nombre entier, il faut faire des multiplications * des puissances de 10, avec l'addition du nombre en cours - "125" -> (sens de droite à gauche avec la puissante croissante) 5*10^0 + 2*10^1 + 1*10^2 * ou alors (sens de gauche à droite avec la puissante décroissante) strlen("125") = len = 3 -> 1*10^(len - 1) + 2*10^(len - 2) ... + 5*10^0

  5. #5
    Membre à l'essai
    Femme Profil pro
    Reconversion professionnelle en web développeur
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Reconversion professionnelle en web développeur

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par foetus Voir le message

    • nombre entier en chaîne de caractères, il faut faire des divisions / 10, avec le modulo pour avoir le chiffre - 125 -> 125 / 10 * 10 = 120, 125 - 120 = 5. Et en recommence tant que (nombre / 10) > 9.
    Merci Foetus de votre retour bien détaillé.

    Je ne comprends pas dans l'exemple en gras, votre manière de faire le modulo. Toutefois, j'ai essayé autrement, mais je ne vois pas comment récupérer le reste de l'opération 125/10 de votre exemple? Voici ce que j'ai fait:

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
     
    void my_putNbr(int nombre);
    void my_putchar(char c);
     
    int main(int argc, char *argv[])
    {
      my_putNbr(-3);
      my_putchar('\n');
      my_putNbr(45);
      my_putchar('\n');
     
      return 0;
    }
     
     
    void my_putNbr(int nombre)
    {
      char conversionEnChar = '0';
    //  int i = 0;
     
      if (nombre < 0)
      {
        my_putchar('-');
        nombre = nombre * (-1);
      }
     
      if (nombre <= 9 && nombre >= 0) // nombre compris entre 0 et 9
      {
        conversionEnChar = nombre + '0';
      }
     else if (nombre > 9)
      {
        nombre = nombre / 10;
        my_putchar(nombre % 10 + '0') ;
      }
     
     
      my_putchar(conversionEnChar);
     
    }
     
    void my_putchar(char c)
    {
      write(1, &c, 1);
    }

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Le modulo est le reste de l'opération.
    Le reste de l'opération 125/10 est donc 125%10
    Son exemple montre comment recréer un modulo avec / et *.
    125/10 est une division entière et retourne 12.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Un des tes problèmes, c'est que nombre = nombre / 10; a lieu au mauvais moment, puisque tu prends le dernier chiffre juste après.
    L'autre problème étant que l'approche "naïve" pour afficher un nombre (afficher le dernier chiffre, diviser par 10, recommencer) aura l'inconvénient d'afficher le nombre à l'envers.

    Pour contrer cela, il y a plusieurs approches:
    • écrire les chiffres dans un tableau de caractères au lieu de la sortie standard, puis afficher ces chiffres dans l'ordre inverse.
    • Rappeler la fonction au milieu de son propre code:
      Code c : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      void afficher_nombre(int nb)
      {
      	if(nb < 0) {
      		my_putchar('-');
      		nb = -nb;
      	}
       
      	if(nb >= 10)
      		afficher_nombre(nb / 10);
      	afficher_chiffre(nb % 10);
      }
    • Faire un calcul plus complexe pour lire les chiffres de gauche à droite.


    PS: Je te conseille de rajouter une fonction intermédiaire pour l'affichage de chaque chiffre:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void my_putchar(char c)
    {
    	write(STDOUT_FILENO, &c, 1);
    }
    void afficher_chiffre(int n)
    {
    	my_putchar((char)( n + '0' ));
    }
    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
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par PetitPanda9 Voir le message
    nombre = nombre * (-1)
    En effet, pourquoi faire simple quand on peut faire compliqué... nombre=-nombre !!!

    Citation Envoyé par PetitPanda9 Voir le message
    Je ne comprends pas dans l'exemple en gras, votre manière de faire le modulo. Toutefois, j'ai essayé autrement, mais je ne vois pas comment récupérer le reste de l'opération 125/10 de votre exemple?
    Ah ben il faut aussi apprendre ses cours et la liste des opérateurs du C. Opérateur "%" = calcul du modulo.
    Et sinon le reste d'une division c'est (appris au primaire) ce qui reste quand on enlève le quotient multiplié par le diviseur => le reste de 125 divisé par 10 est égal à 125 - 125 / 10 * 10 (en se souvenant que les divisions d'int en C se font en int)...
    Mon Tutoriel sur la programmation «Python»
    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
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre à l'essai
    Femme Profil pro
    Reconversion professionnelle en web développeur
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Reconversion professionnelle en web développeur

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Points : 11
    Points
    11
    Par défaut
    [QUOTE=Médinoc;11493752]

    Pour contrer cela, il y a plusieurs approches:
    [list][*]Rappeler la fonction au milieu de son propre code:
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void afficher_nombre(int nb)
    {
    	if(nb < 0) {
    		my_putchar('-');
    		nb = -nb;
    	}
     
    	if(nb >= 10)
    		afficher_nombre(nb / 10);
    	afficher_chiffre(nb % 10);
    }


    Rappeler sa fonction, avant de vous lire, je pensais que c'était une erreur ça me semblait incohérent d'appeler la fonction qu'on est en train d'écrire dans cette fonction même. Mais vous avez validé que c'est une pratique valable. Du coup, ma fonction est opérationnelle. Je l'ai faite simple et surtout je la comprends.

    Merci d'avoir pris le temps de m'expliquer et d'illustrer.

    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
     
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
     
    void my_putNbr(int nombre);
    void my_putchar(char c);
     
    int main(int argc, char *argv[])
    {
      my_putNbr(125);
      my_putNbr(-42);
      my_putchar('\n');
     
      return 0;
    }
     
     
    void my_putNbr(int nombre)
    {
     
      if (nombre < 0) // si le nombre en paramètre est négatif
      {
        my_putchar('-');
        nombre = -nombre; // veut dire nombre * (-1)
      }
     
     if (nombre / 10)
      {
        my_putNbr(nombre / 10) ; 
      }
      my_putchar(nombre % 10 + '0') ;                          
     
    }
     
    void my_putchar(char c)
    {
      write(1, &c, 1);
    }

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Ça s'appelle la récursivité.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par PetitPanda9 Voir le message
    Rappeler sa fonction, avant de vous lire, je pensais que c'était une erreur ça me semblait incohérent d'appeler la fonction qu'on est en train d'écrire dans cette fonction même.
    L'appel ne se fait pas au moment où on est en train de taper le code, il se fait au moment où le programme compilé s'exécute. Et à ce moment là, la fonction est entièrement écrite...
    Mon Tutoriel sur la programmation «Python»
    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
    Et on poste ses codes entre balises [code] et [/code]

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je viens de remarquer un truc, c'est que cette partie du code:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(nb < 0) {
    	my_putchar('-');
    	nb = -nb;
    }
    ne marchera pas sur la plupart des plate-formes si la valeur reçue est INT_MIN (la plupart des plate-formes notant leurs nombres négatifs en complément à 2, -INT_MIN n'est pas une valeur valide).
    Le symptôme le plus courant sera que nb reste égal à INT_MIN, ce qui faussera le modulo (avec un modulo "mathématique", le dernier chiffre sera négatif) et passera un nombre négatif (mais gérable) au premier appel récursif. Le résultat devrait alors ressembler à --214748364-8.

    Ce problème devrait pouvoir être contourné en compliquant un peu le code (gérer la conversion de négatif vers positif après la division par 10 et le modulo).
    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.

  13. #13
    Membre à l'essai
    Femme Profil pro
    Reconversion professionnelle en web développeur
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Reconversion professionnelle en web développeur

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(nb < 0) {
    	my_putchar('-');
    	nb = -nb;
    }
    ne marchera pas sur la plupart des plate-formes si la valeur reçue est INT_MIN (la plupart des plate-formes notant leurs nombres négatifs en complément à 2, -INT_MIN n'est pas une valeur valide).
    Bonjour,

    Qu'entendez-vous par "plate-formes"? Est-ce les systèmes d'exploitation(Linux, Mac, Windows)?

    La fonction n'est pas pensée pour prendre un INT_MIN. Peut-être qu'avec une condition qui exclut cette valeur ça suffirait?

    Merci.

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Besoin d'aide sur les fonctions vba
    Par merveil014 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 14/06/2014, 08h11
  2. NATURAL : Besoin d'aide sur une fonction
    Par Antichoc dans le forum Cobol
    Réponses: 2
    Dernier message: 19/07/2011, 17h00
  3. besoin d'aide sur les fonctions
    Par magic73 dans le forum ActionScript 1 & ActionScript 2
    Réponses: 1
    Dernier message: 20/03/2008, 08h59
  4. Besoin d'aide sur une fonction
    Par PrinceMaster77 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 30/08/2005, 17h40
  5. Besoin d'aide sur les fonction d'interbase
    Par BOUBOU81 dans le forum InterBase
    Réponses: 2
    Dernier message: 05/11/2004, 10h00

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