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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    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
    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
    863
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 863
    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 !

  3. #3
    Membre averti
    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
    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 confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 769
    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 769
    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 averti
    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
    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 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 152
    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
    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
    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
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    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]

+ 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