web-dev-qa-db-fra.com

Comment convertir std :: string_view en double?

J'écris un analyseur c ++ pour un fichier d'options personnalisé pour une application. J'ai une boucle qui lit les lignes sous la forme de option=value à partir d'un fichier texte où value doit être converti en double. En pseudocode, il fait ce qui suit:

while(not EOF)
    statement <- read_from_file
    useful_statement <- remove whitespaces, comments, etc from statement
    equal_position <- find '=' in useful_statement
    option_str <- useful_statement[0:equal_position)
    value_str <- useful_statement[equal_position:end)
    find_option(option_str) <- double(value_str)

Pour gérer le fractionnement de chaîne et le passage aux fonctions, j'utilise std::string_view car il évite une copie excessive et indique clairement l'intention de visualiser les segments d'un _ std::string. J'ai tout fait au point où std::string_view value_str pointe vers la partie exacte de useful_statement qui contient la valeur que je veux extraire, mais je ne sais pas comment lire un double à partir d'un std::string_view.

Je connais std::stod qui ne fonctionne pas avec std::string_view. Ça me permet d'écrire

double value = std::stod(std::string(value_str));

Cependant, c'est moche car il se convertit en une chaîne qui n'est pas réellement nécessaire, et même si cela ne fera vraisemblablement pas de différence notable dans mon cas, cela pourrait être trop lent si l'on devait lire une énorme quantité de nombres dans un texte fichier.

D'un autre côté, atof ne fonctionnera pas car je ne peux pas garantir un terminateur nul. Je pourrais le pirater en ajoutant \0 à useful_statement lors de sa construction, mais cela rendra le code déroutant pour un lecteur et le rendra trop facile à casser si le code est modifié/refactorisé.

Alors, quel serait un moyen propre, intuitif et raisonnablement efficace de le faire?

20
patatahooligan

Puisque vous avez marqué votre question avec C++ 1z, cela signifie (théoriquement) que vous avez accès à from_chars . Il peut gérer votre conversion de chaîne en nombre sans avoir besoin de plus d'une paire de const char*s:

double dbl;
auto result = from_chars(value_str.data(), value_str.data() + value_str.size(), dbl);

Bien sûr, cela nécessite que votre bibliothèque standard fournisse une implémentation de from_chars.

19
Nicol Bolas

En-têtes:

#include <boost/convert.hpp>
#include <boost/convert/strtol.hpp>

Ensuite:

std::string x { "aa123.4"};
const std::string_view y(x.c_str()+2, 5); // Window that views the characters "123.4".

auto value = boost::convert<double>(y, boost::cnv::strtol());
if (value.has_value())
{
    cout << value.get() << "\n"; // Prints: 123.4
}

Compilateurs testés:

  • MSVC 2017

p.s. Peut facilement installer Boost en utilisant vcpkg (par défaut à 32 bits, la deuxième commande est pour 64 bits):

vcpkg install boost-convert
vcpkg install boost-convert:x64-windows
0
Contango