web-dev-qa-db-ja.com

std :: string_viewをdoubleに変換する方法は?

アプリケーションのカスタムオプションファイルのc ++パーサーを書いています。 valuedoubleに変換する必要があるテキストファイルからoption=valueの形式で行を読み取るループがあります。擬似コードでは、次のことを行います。

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)

文字列の分割と関数への受け渡しを処理するには、過剰なコピーを回避し、既存のstd::string_viewのセグメントを表示する意図を明確に示すため、std::stringを使用します。 std::string_view value_strが、抽出したい値を含むuseful_statementの正確な部分を指すようになるまで、すべてを実行しましたが、doublestd::string_viewから。

std::stodでは機能しないstd::string_viewを知っています。それは私が書くことができます

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

ただし、実際には不要な文字列に変換されるため、これは醜く、おそらく私の場合は目立った違いはないとしても、テキストから大量の数値を読み取らなければならない場合は、遅くなる可能性があります。ファイル。

一方、ヌルターミネーターを保証できないため、atofは機能しません。構築時に\0useful_statementを追加してハックすることもできますが、コードが読みにくくなるだけでなく、コードが変更またはリファクタリングされた場合に簡単に壊れてしまいます。

それで、これを行うためのクリーンで直感的で合理的に効率的な方法は何でしょうか?

20
patatahooligan

質問にC++ 1zを付けたので、(理論的には) from_chars にアクセスできることになります。 const char*sのペア以外は必要なく、文字列から数値への変換を処理できます。

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

もちろん、これには標準ライブラリがfrom_charsの実装を提供する必要があります。

19
Nicol Bolas

ヘッダー:

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

次に:

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
}

テスト済みコンパイラ:

  • MSVC 2017

pS vcpkgを使用してBoostを簡単にインストールできます(デフォルトは32ビット、2番目のコマンドは64ビット用):

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