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 :

Une sorte de sprintf retournant un char


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut Une sorte de sprintf retournant un char
    Bonjour à tous,

    Je continue de galérer avec les typages et surtout l'ajout d'un char à un autre, l'appondre. Ayant l'habitude d'utiliser des languages de haut niveau avec typage automatique, je pêche.

    Pour ceux qui conaissent Python, j'aimerais utiliser une formule de ce style dans C++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mysqlpp::Query query = conn.query("SELECT * FROM %s" % (table) );
    C'est à la manière d'un printf ou même sprintf, le problème avec ces deux fonctions c'est qu'elle requière les deux un buffer intermédiaire, je dois donc passer par créer une variable, utiliser sprintf et l'utiliser dans la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char request [255];
    sprintf(request, "SELECT * FROM %s", table);
    mysqlpp::Query query = conn.query(request);
    Ecrire en trois lignes ce qui peut être fait directement en paramètre d'une fonction est plutôt découragant. Est-ce que vous auriez une solution qui me conviendrait ?
    J'ai aussi essayer le truc tout bête qui me paraîssait pourtant juste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mysqlpp::Query query = conn.query("SELECT * FROM"+ *table);
    Mais je n'obtient aucun résultat de la part de ma base de donnée contrairement à la solution donnée ci-dessus, comme si la chaîne était éronnée.

    En résumé, je cherche une fonction qui retournerait une chaîne char (ou un std::String si c'est plus simple?) suivant le formatage que je lui demande des variables, du genre sprintf. Sinon je me tourne vers toutes autres possibilités, je n'ai pas de restriction.

    Merci d'avance.

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Si table est de type string, le code suivant fait ce que tu veux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mysqlpp::Query query = conn.query("SELECT * FROM "+ table);
    Ou bien (je ne sais pas ce que la fonction query attend en paramètre) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mysqlpp::Query query = conn.query(("SELECT * FROM "+ table).c_str());

    Si tu veux aller plus loin, avec de la mise en forme plus évoluée, avec paramètres positionnels par exemple, pour pouvoir faire quelquechose comme (la syntaxe finale ne sera pas exactement ça, c'est pour donner l'idée) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mysqlpp::Query query = conn.query("SELECT %1% FROM %0%", table, fields);
    Tu peux regarder du côté de la bibliothèque boost::format.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut
    Salut JolyLoic,

    Merci de ta réponse,

    Citation Envoyé par JolyLoic Voir le message
    Si table est de type string, le code suivant fait ce que tu veux :
    En effet, j'ai complétement oublié de dire de quel type était table, alors c'est du char. Avec les string je viens d'essayer c'est plus simple, même beaucoup trop. Dans mon cas j'ai dû rajouter le * sinon il ne compilait pas, parce que j'ai définit et utilisé le char de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char *table = "rss";
    [...]
    mysqlpp::Query query = conn.query("SELECT * FROM "+ *table);
    Citation Envoyé par JolyLoic Voir le message
    Ou bien (je ne sais pas ce que la fonction query attend en paramètre) :
    mysqlpp::Query mysqlpp::Connection::query(const char*)
    mysqlpp::Query mysqlpp::Connection::query(const std::string&)
    Appramment query peut prendre un char ou un string en paramètre, oui ça simplifie bien les choses, mais j'ai d'autres fonctions qui ne peuvent prendre que du char. Du coup ça me serait utile de pouvoir m'en sortir sans.


    Citation Envoyé par JolyLoic Voir le message
    Si tu veux aller plus loin, avec de la mise en forme plus évoluée, avec paramètres positionnels par exemple, pour pouvoir faire quelquechose comme (la syntaxe finale ne sera pas exactement ça, c'est pour donner l'idée) :
    [...]
    Tu peux regarder du côté de la bibliothèque boost::format.
    La syntaxe ressemble bien à du sprintf, par contre je trouve génant d'utiliser une librairie externe pour faire des choses "élémentaire".

    Enfin bon, je critique je critique, j'en suis désolé je suis un peu trop exigant. Est-ce qu'il y a une méthode pour les variables de type char plutôt que string du coup ?

    Merci.

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    J'ai li'mpression que tu fais une confusion entre char et char*. Une variable de type char est une variable ayant comme valeur un caractère. Un char * représente un pointeur vers une telle variable. Et dans de nombreuses circonstances, on fait pointer un tel pointeur vers un emplacement mémoire où, à la suite de ce caractère, se trouvent d'autres caractères. Ce qui permet à un char* de servir au final pour désigner non plus un caractère, mais toute une chaîne de caractères.

    Tu dois donc voir pourquoi ton code initial ne marche pas. Un char* n'a pas une sémantique de chaîne de caractères, et ne comprend dont aucune des opérations qui permettent de manipuler une telle chaîne (rechercher un caractère, concaténer deux chaînes...). Il existe des fonctions issues du C qui permettent de faire ce genre de chose sur ces emplacements mémoire, mais comme elles travaillent à bas niveau, elles demandent de gérer explicitement la mémoire (dans ton cas, que de passe-t-il si le nom de ta table fait plus de 255 caractères ?). A mon sens, un cours de C++ peut entièrement passer sous silence toutes ces fonctions travaillant sur des char*, et je dirais même qu'un cours qui en parle trop tôt (c'est à dire avant un appendice sur l'historique et les liens avec le C) gagne tout de suite quelques mauvais points dans mon estime.

    Le vrai type pour gérer des chaînes de caractère en C++ est string. Si jamais tu dois travailler avec des fonctions demandant un char*, le mieux à faire est généralement de travailler quand même avec des strings, puis au dernier moment de demander à sa fonction membre c_str() de nous laisser accéder au char* qui en interne nous sert à implémenter string.

    Personnellement, le nombre de bugs de gestion mémoire dans mes programmes a subit une véritable dégringolade quand j'ai commencé à utiliser les outils haut niveau du C++ pour gérer la mémoire, comme string ou vector.

    Pour le fait de passer par de l'externe, c'est effectivement malheureux, mais il y a tant de choses que l'on peut vouloir faire avec une chaîne de caractère que certaines n'ont pas été prévues de base dans le langage. Et boost::format fait plus que ce que fait sprintf (de mémoire, sprintf ne gère pas les paramètres positionnels), et de manière plus sûre.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut
    Je te remercie énormément de ta réponse. Il est vrai que je confonds un peu le typage, que je connaissais les pointeurs et références, mais il faudrait que je me raffraichisse la mémoire. Ca date un peu

    Sinon concernant les String, ça me convient de les utiliser. En fait je pensais que les String était un peu trop facile, que c'était un peu contourner le problème tu vois. Donc je vais utiliser les variables de type String plutôt que les char ça permet l'allocation dynamique en mémoire etc...
    C'est bien plus pratique et facile ensuite de faire c_str(). Et bien merci infiniment d'avoir pris le temps de répondre.

    Peut-être un jour j'utiliserais la lib boost qui sait. Pour le moment String et printf me suffiront. Merci encore et à bientôt !

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Je voudrais juste intervenir sur
    Citation Envoyé par jamesb Voir le message
    <snip>
    Sinon concernant les String, ça me convient de les utiliser. En fait je pensais que les String était un peu trop facile, que c'était un peu contourner le problème tu vois. Donc je vais utiliser les variables de type String plutôt que les char ça permet l'allocation dynamique en mémoire etc...
    C'est bien plus pratique et facile ensuite de faire c_str(). Et bien merci infiniment d'avoir pris le temps de répondre.
    <snip>
    pour t'insiter à réfléchir sur la partie "à méditer" de ma signature...

    Tu auras compris qu'elle comporte une erreur (voulue), et qu'elle te propose de méditer sur la phrase
    la solution la plus simple est toujours la meilleure


    Les classes proposées par la S(T)L sont fournies par l'ensemble des compilateurs "récents" (mettons tous ceux sortis peu ou prou depuis l'an 2000) et vouloir s'en passer parce que "c'est trop facile" revient, à peu de chose près à vouloir creuser un puits avec un simple bâton...

    Tu y arrivera, certes, mais après bien plus longtemps et de nombreux efforts que tu aurais pu t'éviter si tu avais pris une pelle et une pioche, ou mieux, une machine prévue à cet effet...

    De manière générale, la facilité doit toujours être préférée, que ce soit dans l'utilisation de techniques qui te permettent de l'obtenir ou, dés le départ, dans la mise au point de la logique que tu veux insuffler à ta fonction ou à ton application.

    Le C++ n'est pas un langage réellement compliqué (il peut suffire de quelques heures pour en comprendre la syntaxe de base et connaitre la majorité des mots clés) mais c'est un langage plus complexe que d'autres langages similaires, ce qui fait qu'il faut sans doute plusieurs années avant de pouvoir considérer que tu le maîtrise (je le pratique depuis plus de trois ans, et je n'en ai pas fait le tour )

    Tu auras largement l'occasion de faire des choses complexes et d'un niveau allant de "difficile" à "presque impossible" pour vouloir - au minimum - utiliser les méthodes les plus sécurisantes à l'emploi

    Or, s'il y a une chose qui est certaine, c'est que les mauvaises habitudes sont d'autant plus difficiles à perdre qu'elles sont anciennes et mauvaises (ceux qui ont déjà essayé d'arrêter de fumer le confirmeront ).

    C'est pourquoi, il faut vraiment s'habituer à utiliser ces méthodes "simples et sécurisantes" dés le départ, de manière à ce que cela devienne une sorte de "seconde nature"

    Ce n'est qu'une fois que les bonnes habitudes sont prises et profondément ancrées qu'il *peut s'avérer* (et encore, c'est sujet à discussion ) utile de s'intéresser à "l'autre coté du miroir" et aux méthodes qui, plus compliquées et moins sécurisantes, sont *parfois* de nature à te faire gagner un peu de performances par rapport aux méthodes simples et sécurisantes
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. Utiliser une bibliothèque C retournant un char*
    Par prgasp77 dans le forum Caml
    Réponses: 8
    Dernier message: 09/08/2009, 13h45
  2. Réponses: 12
    Dernier message: 12/03/2006, 15h53
  3. Une sorte de planning (leger) en etât ou formulaire
    Par wulfgar57 dans le forum Access
    Réponses: 2
    Dernier message: 09/12/2005, 18h52
  4. Une fonction peut-elle retourner plusieurs résultats ?
    Par aragorns dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 26/03/2005, 22h18
  5. Gestion OnChange sur une sorte d'éditeur de propriétés
    Par Clorish dans le forum Composants VCL
    Réponses: 8
    Dernier message: 29/09/2004, 09h59

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