アプリケーションのカスタムオプションファイルのc ++パーサーを書いています。 value
をdouble
に変換する必要があるテキストファイルから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
の正確な部分を指すようになるまで、すべてを実行しましたが、double
std::string_view
から。
std::stod
では機能しないstd::string_view
を知っています。それは私が書くことができます
double value = std::stod(std::string(value_str));
ただし、実際には不要な文字列に変換されるため、これは醜く、おそらく私の場合は目立った違いはないとしても、テキストから大量の数値を読み取らなければならない場合は、遅くなる可能性があります。ファイル。
一方、ヌルターミネーターを保証できないため、atof
は機能しません。構築時に\0
にuseful_statement
を追加してハックすることもできますが、コードが読みにくくなるだけでなく、コードが変更またはリファクタリングされた場合に簡単に壊れてしまいます。
それで、これを行うためのクリーンで直感的で合理的に効率的な方法は何でしょうか?
質問に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
の実装を提供する必要があります。
ヘッダー:
#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
}
テスト済みコンパイラ:
pS vcpkgを使用してBoostを簡単にインストールできます(デフォルトは32ビット、2番目のコマンドは64ビット用):
vcpkg install boost-convert
vcpkg install boost-convert:x64-windows