Comment convertir un flottant en chaîne en C ++ tout en spécifiant la précision et le nombre de chiffres décimaux?
Par exemple: 3.14159265359 -> "3.14"
c++
string
floating-point
Shannon Matthews
la source
la source
Réponses:
Une manière typique serait d'utiliser
stringstream
:#include <iomanip> #include <sstream> double pi = 3.14159265359; std::stringstream stream; stream << std::fixed << std::setprecision(2) << pi; std::string s = stream.str();
Voir fixe
et définir la précision .
Pour conversions à des fins techniques , comme le stockage de données dans un fichier XML ou JSON, C ++ 17 définit la famille de fonctions to_chars .
En supposant un compilateur conforme (qui nous manque au moment de la rédaction), quelque chose comme ça peut être envisagé:
#include <array> #include <charconv> double pi = 3.14159265359; std::array<char, 128> buffer; auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), pi, std::chars_format::fixed, 2); if (ec == std::errc{}) { std::string s(buffer.data(), ptr); // .... } else { // error handling }
la source
La méthode habituelle pour faire ce genre de chose est d '«imprimer dans une chaîne». En C ++, cela signifie utiliser
std::stringstream
quelque chose comme:std::stringstream ss; ss << std::fixed << std::setprecision(2) << number; std::string mystring = ss.str();
la source
Une autre option est
snprintf
:double pi = 3.1415926; std::string s(16, '\0'); auto written = std::snprintf(&s[0], s.size(), "%.2f", pi); s.resize(written);
Démo . La gestion des erreurs doit être ajoutée, c'est-à-dire la vérification
written < 0
.la source
snprintf
mieux dans ce cas? Veuillez expliquer ... Ce ne sera certainement pas plus rapide, produisez moins de code [J'ai écrit une implémentation printf, c'est assez compact avec un peu moins de 2000 lignes de code, mais avec des extensions de macro, cela atteint environ 2500 lignes]__printf_fp
fonctionnalités sous-jacentes - il est plutôt étrange que cela prenne tellement plus de tempsstringstream
, car cela ne devrait vraiment pas avoir à le faire.Vous pouvez utiliser la
fmt::format
fonction de la bibliothèque {fmt} :#include <fmt/core.h> int main() std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14" }
où
2
est une précision.Cette fonction de formatage a été proposée pour la normalisation en C ++: P0645 . P0645 et {fmt} utilisent tous deux une syntaxe de chaîne de format semblable à Python qui est similaire à celle de
printf
's mais qui utilise{}
comme délimiteurs au lieu de%
.la source
Voici une solution utilisant uniquement std. Cependant, notez que cela arrondit seulement vers le bas.
float number = 3.14159; std::string num_text = std::to_string(number); std::string rounded = num_text.substr(0, num_text.find(".")+3);
Car
rounded
cela donne:3.14
Le code convertit tout le flottant en chaîne, mais coupe tous les caractères 2 caractères après le "."
la source
number + 0.005
dans mon cas.Ici, je donne un exemple négatif où vous voulez éviter lors de la conversion de nombres flottants en chaînes.
float num=99.463; float tmp1=round(num*1000); float tmp2=tmp1/1000; cout << tmp1 << " " << tmp2 << " " << to_string(tmp2) << endl;
Vous obtenez
99463 99.463 99.462997
Remarque: la variable num peut être n'importe quelle valeur proche de 99,463, vous obtiendrez la même impression. Le but est d'éviter la fonction pratique "to_string" de c ++ 11. Il m'a fallu un certain temps pour sortir ce piège. Le meilleur moyen est les méthodes stringstream et sprintf (langage C). C ++ 11 ou plus récent doit fournir un deuxième paramètre comme nombre de chiffres après la virgule flottante à afficher. Pour le moment, la valeur par défaut est 6. Je pose ceci pour que d'autres ne perdent pas de temps sur ce sujet.
J'ai écrit ma première version, faites-le moi savoir si vous trouvez un bogue qui doit être corrigé. Vous pouvez contrôler le comportement exact avec l'iomanipulator. Ma fonction est d'afficher le nombre de chiffres après la virgule décimale.
string ftos(float f, int nd) { ostringstream ostr; int tens = stoi("1" + string(nd, '0')); ostr << round(f*tens)/tens; return ostr.str(); }
la source