2017-08-11 176 views
8

我正在为应用程序的自定义选项文件编写C++解析器。我有一个循环,以文本文件的形式从option=value中读取行,其中value必须转换为double。在伪代码将执行以下操作:如何将std :: string_view转换为double?

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的确切部分,其中包含我想要提取的值,但我无法弄清楚从std::string_view读取double的方法。

我知道std::stod哪个不能与std::string_view一起使用。这让我写

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

然而,这是丑陋的,因为它转化为实际不需要一个字符串,即使它可能不会在我的情况下,一个明显的区别,它可能是,如果速度太慢必须从文本文件中读取大量的数字。

另一方面,atof将无法​​正常工作,因为我无法保证空终止符。当构建它时,我可以通过将\0添加到useful_statement来破解它,但是如果代码被更改/重构,这会使代码对读者感到困惑,并且使代码变得容易中断。

那么,干净,直观和合理有效的方法是什么?

+1

你确定使用boost吗?我认为你可以用'boost :: convert (stringview);'做到这一点。我从这里得到了...在页面上最后的评论https://github.com/boostorg/convert/issues/29 –

+1

很好的发现。尽管如此,它可能是'boost :: convert (stringview,stringview.length())'。它肯定比转换为字符串更清晰,希望更快。唯一的缺点是增加了一个额外的依赖。 – patatahooligan

+0

偏题:显然这是psuedocode,但要注意如何实现“while(not EOF)”。简单的'while(!stream.eof())'有一些令人讨厌的陷阱。 – user4581301

回答

10

由于您用C++ 1z标记了您的问题,那么(理论上)意味着您有权访问from_chars。它可以处理你的字符串到数字的转换,而无需任何超过一对const char* S:

double dbl; 
auto result = from_chars(&value_str[0], &value_str[0] + value_str.size(), dbl); 

当然,这需要你的标准库提供的from_chars的实现。 Libstdc++ does not,或does libc++。或者Visual Studio,就此而言。

+0

'from_chars()'需要一个'double&'而不是'double *'。也是这样一个尴尬的界面...鉴于没有人提供它,也许这是一个很好的机会,它需要一个'string_view' ... – Barry

+1

这正是我正在寻找,如果它的实施。为了便于阅读,我建议将此调用更改为'from_chars(&value_str.front(),&value_str.back(),dbl)'。 @Barry:没有太多理由需要使用'string_view'使用'char *'使其具有通用性,并且从'string_view'获取这些内容是很简单的。 – patatahooligan

+0

@Barry:如果'basic_string_view'保证它的迭代器是*指针*,那将会不那么尴尬。 –