HOWTO · C++

Comment convertir un float en chaîne de caractères en C++

Cet article montre comment convertir un float en chaîne de caractères en C++.

Sur cette page

Pour convertir rapidement une valeur à virgule flottante calculée à l’exécution en chaîne, utilisez std::to_string ; choisissez un flux de chaînes si vous devez contrôler le format, ou snprintf si une API exige un tableau de caractères. La stringification par le préprocesseur est différente : elle transforme les jetons du code source en texte et ne peut pas examiner une valeur calculée pendant l’exécution.

Utiliser std::to_string pour une conversion rapide

std::to_string, déclarée dans <string>, accepte les valeurs à virgule flottante et renvoie un std::string. Elle est pratique pour l’affichage ou la journalisation lorsque le format par défaut convient. La représentation exacte peut dépendre de la bibliothèque C++ et de sa version ; évitez donc de supposer que toutes les chaînes d’outils produiront le même résultat décimal.

Exécutez cet exemple :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

#include <iostream>
#include <string>

int main() {
  double value = 12.5;
  std::string text = std::to_string(value);
  std::cout << text << '\n';
}

La chaîne contient du texte formaté ; elle ne modifie pas la valeur stockée dans value. Une valeur très petite peut s’afficher comme zéro si le format décimal choisi ne montre pas assez de décimales. Si le nombre de décimales compte, choisissez explicitement un formateur au lieu de supposer que la représentation par défaut conservera le niveau de détail souhaité.

Contrôler le format décimal avec un flux de chaînes

Utilisez std::stringstream, déclaré dans <sstream>, pour bénéficier des commandes de formatage habituelles des flux. std::fixed fait en sorte que la précision désigne le nombre de chiffres après la virgule, et std::setprecision, déclaré dans <iomanip>, définit ce nombre. Sans std::fixed, la précision du flux a un autre sens : elle désigne le nombre de chiffres significatifs.

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

int main() {
  double value = 12.34567;
  std::stringstream stream;
  stream << std::fixed << std::setprecision(2) << value;
  std::string text = stream.str();
  std::cout << text << '\n';
}

str() renvoie une chaîne par valeur. Si vous avez besoin d’un pointeur de caractères à la manière du C, conservez cette chaîne en vie : std::string text = stream.str();, puis const char* ptr = text.c_str();. Les caractères restent valides tant que text existe et n’est pas modifiée. Ne récupérez pas c_str() sur la chaîne temporaire renvoyée par stream.str() pour conserver le pointeur au-delà de cette expression complète : l’objet temporaire est détruit à la fin de l’expression.

Convertir des constantes de compilation en texte avec des macros

L’opérateur de stringification # du préprocesseur transforme en littéral chaîne les jetons écrits pour un argument de macro. Cette méthode convient aux constantes du code source, mais ne convertit pas une valeur à virgule flottante calculée à l’exécution et n’applique aucun formatage numérique. Avec une macro directe, un argument qui est lui-même un nom de macro est stringifié tel quel. Une macro à deux niveaux développe d’abord ce nom :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

#include <iostream>

#define STRINGIZE_INNER(x) #x
#define STRINGIZE(x) STRINGIZE_INNER(x)
#define RATE 2.75

int main() {
  const char* text = STRINGIZE(RATE);
  std::cout << text << '\n';
}

Le résultat représente les jetons du code source après expansion. Il ne s’agit pas d’une conversion à l’exécution d’un float, et les macros ne permettent ni l’arrondi, ni le choix du nombre de décimales, ni le formatage selon les paramètres régionaux.

Formater dans un tableau de caractères avec snprintf

Choisissez snprintf, déclarée dans <cstdio>, lorsqu’une API C exige un tableau de caractères de capacité limitée. Indiquez la capacité du tableau, puis examinez la valeur de retour : une valeur négative signale un échec de formatage, tandis qu’une valeur supérieure ou égale à la capacité signifie que le texte complet n’a pas tenu. Si la capacité est supérieure à zéro, le tableau se termine par un caractère nul, même lorsque le texte a été tronqué.

Les messages affichés «Formatting failed» et «Buffer too small» restent en anglais dans l’exemple.

#include <cstddef>
#include <cstdio>
#include <iostream>

int main() {
  double value = 12.34567;
  char buffer[32];
  int result = std::snprintf(buffer, sizeof buffer, "%.2f", value);

  if (result < 0) {
    std::cout << "Formatting failed\n";
  } else if (static_cast<std::size_t>(result) >= sizeof buffer) {
    std::cout << "Buffer too small\n";
  } else {
    std::cout << buffer << '\n';
  }
}

Le format %.2f demande deux chiffres après la virgule. Avant d’utiliser le résultat, vérifiez à l’aide de la valeur de retour de snprintf que le texte complet tient dans le tableau. Évitez sprintf sans limite de taille : cette fonction ne prend pas la capacité du tableau en argument et peut écrire au-delà de ses limites.

Choisir une méthode de conversion selon vos besoins

Pour une conversion simple à l’exécution, commencez par std::to_string. Si vous devez définir explicitement le format décimal, utilisez un flux de chaînes avec std::fixed et std::setprecision. Réservez la stringification par macro au texte issu de jetons connus à la compilation, et choisissez snprintf pour écrire dans un tableau borné à la manière du C. Dans tous les cas, distinguez la valeur numérique de sa représentation textuelle : le formatage détermine ce que le lecteur voit, tandis que la valeur flottante d’origine reste inchangée.