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 :

string en char*


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut string en char*
    Bonjour,
    J'ai une fonction qui prend en paramètre un LPVOID soit un char* ou voir unsigned char* pour écrire dedans (me renvoyé le resultat)

    J'aimerais bien utilisé le string ici pour pas a avoir a utilisé malloc free etc donc comment je peut faire ça depuis un string ? comment la fonction peut m'écrire dans mon std::string ?

    si c'est trop compliqué je vais utilisé un char* et puis c'est tout...

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    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 153
    Billets dans le blog
    4
    Par défaut
    Salut,

    on a beau attendre un char*, utiliser string n'est pas la bonne chose à faire.
    Ce qu'il faut utiliser c'est vector ou array.
    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.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    une std::string n'est pas adaptée pour servir de buffer de réception. Des optimisations internes font que même si la destination finale est une std::string, il est plus optimum de passer par un intermédiaire.
    Le buffer LPVOID doit avoir une taille préconisée maximum, dans ce cas un simple tableau doit être utilisé, il faut éviter les allocations mémoire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    constexpr size_t LgMax = 100;
    std::array<char,LgMax> buffer;
    fonction( buffer , buffer.size() );  // requête fonction C en indiquant la taille max
    // après contrôle que tout est okay
    std::string str_result{ buffer.data() };
    // ou si la fonction a retourné la longueur lg, on peut aussi faire
    str.assign( buffer.begin() , buffer.begin()+lg );

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,
    Citation Envoyé par dalfab Voir le message
    il faut éviter les allocations mémoire.
    Je suis tout à fait d'accord avec le principe, mais encore faut il voir la taille du tampon...

    Si cette taille est de "quelques dizaines" de bytes, le fait d'éviter l'allocation de mémoire ne devrait pas poser de problèmes (à moins, bien sur, d'en arriver à multiplier les tampons, dans un appel récursif qui nous aurait échappé, par exemple).

    Mais, dés que la taille du tampon devient "trop importante" (ne serait-ce que 65 535 -- voire moins (16 mille et une fafiote )-- qui correspond, en gros, à la valeur maximale représentable à l'aide d'un short), je crois quand même que l'utilisation d'un std::vector se justifie pleinement pour éviter les stack overflow...
    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

  5. #5
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Cette discussion soulève toute la difficulté à mélanger du C++ avec C

    Mais il y a des solutions et les gourous qui pensent le C++ ont enfin trouvé la parade
    Je prends donc les autres intervenants à contre-pied pour affirmer que, oui, on peut utiliser std::string pour appeler une fonction qui demande un char *.
    C'est ainsi que depuis C++17 la methode data() est (enfin !) déclinée en une deuxième version non const qui renvoit un char *.

    Perso j'utilise depuis très longtemps du code dans ce genre avec succès:
    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
    std::wstring StrDateTime(bool localtime)
    {
    	SYSTEMTIME st;
    	if (!localtime)
    		GetSystemTime(&st);
    	std::wstring sdt(31, '\0');
    	int len = GetDateFormatEx(
    		LOCALE_NAME_INVARIANT, 0ul, localtime ? NULL : &st,
    		L"yyyy'-'MM'-'dd ", &sdt[0], (int)sdt.size(), NULL) - 1;
    	len += GetTimeFormatEx(
    		LOCALE_NAME_INVARIANT, 0ul, localtime ? NULL : &st,
    		L"HH':'mm':'ss", &sdt[len], (int)sdt.size() - len) - 1;
    	sdt.resize(len);
    	return sdt;
    }
    Il suffit d'être prudent et bien comprendre ce que fait la fonction qui demande un char *

  6. #6
    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
    Mais est-ce que la plate-forme sur laquelle imprimante compile supporte C++17, là est la question.
    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.

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par camboui Voir le message
    C'est ainsi que depuis C++17 la methode data() est (enfin !) déclinée en une deuxième version non const qui renvoit un char *.
    Oui, enfin, l'utilisation de data() au lieu de c_str() ne va résoudre qu'une partie du problème, et en ignorer royalement deux autres:
    D'un coté, data() permet, effectivement, de fournir un char * dont le contenu peut être modifié par une fonction C, mais
    1. la fonction qui reçoit ce char * doit veiller à ne pas dépasser la taille du tableau qu'il représente et
    2. l'idée de ce char * reste de représenter ... une chaine de caractères. Or, un tempon peut envisager d'utiliser -- par exemple -- quatre byte pour représenter un (unsigned) int, et la valeur de ce (unsigned) int (*) pourrait tout à fait contenir un ou plusieurs byte(s) nul(s) et / ou correspondant à un / des caractère(s) particulier(s) (typiquement : n'importe quel caractère dont la valeur est comprise entre 0 et 31 inclus)

    (*) le tout, sans même considérer le problème du boutisme utilisé pour la représentation de cette valeur.

    Nous sommes bien d'accord sur le fait que le premier point soulevé ici est commun à std::string et à std::vector</*unsigned*/ char>.

    Mais le gros problème viendra du deuxième point, spécifique à l'utilisation de std::string, qui considérera forcément chaque byte comme un caractère, et qui l'interprétera en conséquence.

    C'est sans doute la raison qui a fait que, nous disposons , depuis C++17, de std::byte qui nous permet justement d'éviter la confusion entre la valeur numérique d'un caractère et son interprétation ASCII.

    Et c'est la raison pour laquelle, quitte à avoir un tampon "de taille fixe" (à l'exécution), il est largement préférable d'opter pour std::vector<std::byte> si la taille du tampon est définie à l'exécution ou pour std::array<std::byte, taille_predefinie> si la taille peut être définie à la compilation et qu'elle ne pose pas de problème en terme d'utilisation de la pile.
    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. [DEBUTANT] String et char, bug
    Par FinalSpirit dans le forum Débuter
    Réponses: 15
    Dernier message: 10/01/2006, 18h42
  2. Borland + sqlite (aducom) + string > 256 char = pas conte
    Par spyroux dans le forum C++Builder
    Réponses: 1
    Dernier message: 16/12/2005, 22h48
  3. Evaluation d'une variable string ou char* en C++
    Par Coelacanthe dans le forum SL & STL
    Réponses: 2
    Dernier message: 08/11/2005, 09h27
  4. Convertir String en Char: comment?
    Par nmathon dans le forum Langage
    Réponses: 2
    Dernier message: 22/08/2005, 20h58
  5. [Debutant(e)]limitation du String 65536 char
    Par srane dans le forum API standards et tierces
    Réponses: 8
    Dernier message: 28/05/2004, 23h42

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