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 :

De string à code ASCII


Sujet :

C++

  1. #1
    Membre confirmé
    Homme Profil pro
    retraité
    Inscrit en
    Septembre 2010
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Septembre 2010
    Messages : 113
    Par défaut De string à code ASCII
    Salut à tous,
    Comment, SVP, obtenir le code ASCII de la lettre extraite dans ce bout de code?
    D'après la FAQ, j'ai cru comprendre qu'il fallait d'abord convertir cette lettre en 'char', mais je n'ai pas compris l'explication ni l'exemple qui est donné.

    Merci d'avance.
    L.P.
    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
     
    #include <iostream>
     
    using namespace std;
     
    int main()
    {
        string str("Hello");
        string sub = str.substr(1,1); // Extraction de la deuxieme lettre seulement
    // Ici je souhaiterais obtenir le code ASCII de la lettre extraite ci- dessus
     
        cout << sub << endl;
     
        return 0;
    }

  2. #2
    Membre éclairé Avatar de supaplex
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Avril 2012
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Avril 2012
    Messages : 47
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <iostream>
     
    using namespace std;
     
    int main()
    {
        string str("Hello");
        string sub = str.substr(1,1); // Extraction de la deuxieme lettre seulement
    // Ici je souhaiterais obtenir le code ASCII de la lettre extraite ci- dessus
     
        cout << int(sub[0]) << endl;
     
        return 0;
    }

  3. #3
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 759
    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 759
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        string str("Hello");
        const char* ascii_str = str.c_str();
     
        if ((str.length() > 1) && (ascii_str != NULL)) {
            printf("%d", ascii_str[1]);
        }

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    Comme tout le monde s'y met....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <iostream>
    #include <string>
     
    int main()
    {
        std::string str("Hello");
        std::cout << int(sub[1]) << std::endl;
    }
    Au passage, il n'y a aucune raison d'utiliser substr.

  5. #5
    Membre confirmé
    Homme Profil pro
    retraité
    Inscrit en
    Septembre 2010
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Septembre 2010
    Messages : 113
    Par défaut
    Salut à tous,
    Merci pour vos promptes réponses.
    J'ai hâte de les essayer toutes.
    Merci encore à Koala01 pour son message à propos des conditionnelles que j'ai découvert par hasard en 'postant' celui en cours.
    Je lui promets de faire l'exercice qu'il m'a donné dés que j'ai fini celui-là.

    L.P.

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Comme tu as eu plein de code, mais pas d'explications, en voici:

    la fonction string::substr retourne une string.
    l'opérateur [] (string::operator[]) retourne un char.

    les opérateurs << de ostream sont nombreux, le compilateur cherche le plus adapté aux types des opérandes.
    Il trouve respectivement:
    1. operator << (ostream &, string const&), qui affiche la chaine complete
    2. ostream::operator << (char), qui affiche le caractère


    Mais il en existe d'autres, potentiellement plus intéressant. Par exemple, ostream::operator << (int), qui affiche un entier.
    La solution est donc de faire choisir celle-ci au compilateur, en convertissant le caractère à afficher.

    Il y a plusieurs solutions, parmi:
    • le vieux cast à la C, qui est déconseillé, voire déprécié: cout << (int) (str[1]) << endl;
    • la conversion "fonction style", c'est à dire la notation "constructeur de int": cout << int(str[1]) << endl;
    • la conversion explicite: cout << static_cast<int>(str[1]) << endl;

    Je recommande vivement cette dernière: elle explicite parfaitement qu'on fait une conversion, et on peut rechercher facilement ce mot clé static_cast (idéalement, je chercherai "_cast").


    Note que str.sub(1, 1)[0] retourne la même valeur que str[1] (à ceci près que c'est une référence sur une copie du caractère original).

  7. #7
    Membre confirmé
    Homme Profil pro
    retraité
    Inscrit en
    Septembre 2010
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Septembre 2010
    Messages : 113
    Par défaut
    Salut à tous et en particulier à 'ternel' pour ses explications académiques.
    Pour situer le problème je dois dire si que jadis.. j'ai développé quelques applications de gestion en VBA exclusivement pour Excel et Access, je m'initie à peine (2 ou 3 semaines) à C++ avec pour support (en + du site, bien entendu) les livres: "Apprendre le C++", de Claude Delannoy et "Programmez avec le langage c++", de Mathieu Nebra et Matthieu Schaller.
    Je n'ai pas dépassé la page 100 de chacun d'eux et je n'ai pas encore trouvé mes 'marques' avec l'éditeur Code::Blocks. Les choses décantent lentement.
    Je m'essaye à quelques exercices pour me familiariser avec la syntaxe mais,
    -le vieux cast à la C...
    -la conversion "fonction style"...
    -la notation "constructeur de int"...
    et
    -la conversion explicite...
    ne me parlent pas encore mais j'espère que ça va venir.
    En tous cas j'ai scrupuleusement recopié toutes ces explications dont je ne doute pas que dans quelques mois elles me seront parfaitement familières.

    Merci encore.

    P.S.
    le code de 'foetus' ne s'est pas compilé. Il doit manquer un include quelque chose. C'est dommage car j'aurais bien voulu comprendre la conditionnelle qu'il a ajouté.

    L.P.

  8. #8
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 759
    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 759
    Par défaut
    Citation Envoyé par luc pic Voir le message
    le code de 'foetus' ne s'est pas compilé. Il doit manquer un include quelque chose. C'est dommage car j'aurais bien voulu comprendre la conditionnelle qu'il a ajouté.
    Non, il te manque la notion de namespace

    Parce que faire un #include <iostream> n'est pas suffisant. La classe string (comme toutes les autres de la STL), font partie du namespace std: donc std::string.

    Sinon, mon test n'est pas sorcier contrairement à tout le monde, je teste s'il y a au moins 2 caractères parce que si ta chaîne est vide ou a un seul caractère XXX[1] plante.
    L'autre test c'est juste pour vérifier que la chaîne C encapsulée par la classe string a bien été retournée (du moins son pointeur).

  9. #9
    Membre confirmé
    Homme Profil pro
    retraité
    Inscrit en
    Septembre 2010
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Septembre 2010
    Messages : 113
    Par défaut
    Salut à tous,
    C'est sûr que le test de 'foetus' est très intéressant parce que justement j'essaye des contrôles de saisie et pour l'instant c'est pas au top.

    Mais le journal de génération dit, entre autres choses:

    ||=== Générer : Debug dans projet_02 (compilateur : GNU GCC Compiler) ===|
    .... projet_02\main.cpp|13|error: 'printf' was not declared in this scope|
    ||=== Génération de échoué : 1 erreur(s), 0 avertissement(s) (0 minute(s), 0 seconde(s)) ===|

    L.P.

    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
     
    #include <iostream>
     
    using namespace std;
     
    int main()
    {
      string str("Hello");
        const char* ascii_str = str.c_str();
     
        if ((str.length() > 1) && (ascii_str != NULL)) {
            printf("%d", ascii_str[1]);
        }
        return 0;
    }

  10. #10
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    printf est une fonction de la bibliothèque C déclarée dans le header cstdio qui formate et envoie des informations sur la sortie standard. Remplace l'appel par l'idiome std::cout << que tu utilisais jusqu'à présent.

  11. #11
    Membre confirmé
    Homme Profil pro
    retraité
    Inscrit en
    Septembre 2010
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Septembre 2010
    Messages : 113
    Par défaut
    page 29 du Cours de C/C++ Par Christian Casteyde sur ce site, je viens de trouver un #include <stdio.h> qui résout le problème.
    Merci à tous.

  12. #12
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 759
    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 759
    Par défaut
    Citation Envoyé par luc pic Voir le message
    page 29 du Cours de C/C++ Par Christian Casteyde sur ce site, je viens de trouver un #include <stdio.h> qui résout le problème.
    Merci à tous.
    Non surtouuuuuuuuuuuuuuut pas

    Lorsqu'on code en C++, toutes les entêtes C ont été converties ainsi #include <XXX.h> -> #include <cXXX>.

    Par exemple, cstdio, csdtlib, ctime, ... La documentation officielle avec tout: printf

  13. #13
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    @foetus: std::string::c_str() retourne toujours une chaîne valide, tester le pointeur est totalement inutile.

    @luc pic: les bouquins de Claude Delannoy ont mauvaises réputations et le cours Mathieu Nebra et complètement à la ramasse, suffit de regarder le forum d'OC pour voir les reproches qui lui sont fait. Pour finir un cours qui t'enseigne C/C++ ne t'apprendra ni le C, ni le C++.
    Comme bon livre il y a C++ primer, 5e édition de Lipmann

  14. #14
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    Personne ne propose simplement le .at( 2 ) ?

    Genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    std::string s{ "salut" };
    char c = s.at( 2 )
     
    if( c == 108 )
    {
       std::cout << "c'est un l" << std::endl;
    }
    Si tu veux tester ça suffit.

    C'est quand tu dois l'afficher avec std::cout que par défaut il va falloir le caster en quelque chose d'autres que char, mais c'est juste une question d'affichage.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      std::cout << static_cast< int >(c) << std::endl;

  15. #15
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    .at fait plus que tester la présence de l'index, elle lance une exception s'il n'est pas disponible et crash méchamment le programme avec une erreur incompréhension pour l'utilisateur si l'exception n'est pas rattrapée.

    PS: 108 -> 'l', plus lisible.

  16. #16
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 512
    Par défaut
    D'ailleurs, l'exception lancée par std::string::at est de type std::out_of_range qui dérive de std::logic_error qui est un type d'exception qui sert normalement à rattraper une erreur de programmation.

    Doc de std::logic_error :
    « It reports errors that are a consequence of faulty logic within the program such as violating logical preconditions or class invariants and may be preventable. »

    std::logic_error et ses types dérivés se combinent bien avec assert :
    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
    #include <iostream>
    #include <string>
    #include <cassert>
     
    char premiereLettre(const std::string& nom)
    {
        assert(nom.length() > 0); // en Debug, arrête le programme si nom.length() == 0
        return nom.at(0); // lance une exception std::out_of_range si nom.length() == 0
    }
     
    int main() {
        try {
            std::string nom;
            char c = premiereLettre(nom);
            std::cout << "Premiere lettre : '" << c << "'.";
        } catch(std::logic_error& e) {
            std::cerr << "Erreur de programmation : " << e.what();  
        } catch(std::exception& e) {
            std::cerr << "Erreur : " << e.what();
        }
        return 0;
    }
    Si cela ne doit pas être considéré comme une erreur de programmation, alors il vaut mieux lancer un std::range_error qui dérive de std::runtime_error :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char premiereLettre(const std::string& nom)
    {
        if(nom.length() == 0)
            throw std::range_error("Un nom vide n'a pas de premiere lettre.");
        return nom[0];
    }

  17. #17
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    Ca crashe pas le programme, ça lance une exception, c'est quand même différent.

    Je vois pas trop le problème d'utiliser ça par défaut, quand on ne connait pas le domaine d'application du prog original.

    Pour moi, par défaut, on utilise des exceptions et du safe et on évite de tout gérer (mal) à la main. Parce que si tu vérifies jamais que ton indice est dans la string, là oui ça crashe méchant (ou pire, ça crashe pas).

  18. #18
    Membre confirmé
    Homme Profil pro
    retraité
    Inscrit en
    Septembre 2010
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Septembre 2010
    Messages : 113
    Par défaut
    Salut à tous,
    Et merci à Matt, hier nos envois se sont croisés.
    Effectivement en remplaçant 'printf' par 'cout' c'est ok et la conditionnelle de foetus est impécable.
    Je mets de coté le .at(2) de nikko pour plus tard. J'ai un peu de mal à faire le tri dans toutes ces explications qui ne sont pas de mon niveau.

    Merci à tous.

    P.S. pour nikko34 qui s'intéroge sur le domaine d'application du programme original.

    Dans le cadre de cet apprantissage, je me suis donné comme excercice la résolution d'équation du second degré en essayant d'inclure dans le code un maximum de 'procédures' entrées, sorties, contrôles, boucles for, while, condions, etc. comme une sorte de lexique syntaxique d'application.
    Ce n'est pas trés compliqué mais quand on débute ça demande beaucoup d'attention.
    L.P.

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

Discussions similaires

  1. convertir code ascii a string
    Par chadj dans le forum NetBeans
    Réponses: 1
    Dernier message: 02/05/2013, 13h24
  2. [Débutant] Code Ascii dans variable de type string
    Par Nixeus dans le forum C#
    Réponses: 2
    Dernier message: 03/01/2012, 15h32
  3. Remplacer char dans string par code ASCII
    Par ThomasParis dans le forum Langage
    Réponses: 2
    Dernier message: 16/07/2010, 11h47
  4. transformer code ascii en string ?
    Par italiasky dans le forum Langage
    Réponses: 1
    Dernier message: 20/10/2008, 11h39
  5. [String]Comment etendre le mon Code ASCII??
    Par lanfeustdetroll dans le forum API standards et tierces
    Réponses: 24
    Dernier message: 25/07/2005, 14h42

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