将部分非数字字符串转换为double

时间:2015-10-17 13:09:11

标签: c++-cli

我试图将字符串转换为double,也包含非数字字符。我想知道是否有一个通用的解决方案,而不是找到字符串中每个非数字字符的索引并逐个删除它们。 (像atof())

例如,这是我的字符串行(2个矢量坐标):

" [12,75082301 28,53644171 119,392771] [108,4213282 30,04183776 77,14237388]" (由\ t和双引号分隔,包含在字符串中)

我将tindo分割成一个字符串数组

array<String^> ^columns;
columns = line->Split('\t');

在我的第一栏中:&#34; [12,75082301

在我的第三栏中: 119,392771]

有没有一种简单的方法可以使用相同的方法将thoose字符串转换为double?

(并跟进问题:如果有2&#39; \ t&#39; directli彼此相邻,使用StringSplitOption :: RemoveEmptyEntries我应该可以跳过空条目,但似乎没有为我工作......任何想法?)

1 个答案:

答案 0 :(得分:0)

如果你的&#34;非数字&#34;字符可以出现在字符串中的任何位置(即在数字的中间&#34; 1,123 [456&#34;])然后你就不能对字符串进行预处理并删除它们。幸运的是,您可以使用std::remove_if std::copy_if算法一次性完成此操作。

但是,如果你的&#34;非数字&#34;字符只出现在字符串的开头或结尾,你实际上可以将它们视为空格和&#34; split&#34;正确使用带有自定义区域设置的stringstream字符串。定义一个将[]\t视为空格的构面,您将会感到高兴。这样做还会处理您的第二个问题 - 几个相邻的\t字符。

除此之外,您还可以定义另一个将,视为小数点的方面。将它与前一个结合使用,您可以直接从原始字符串中读取double

这是执行所有这些操作的代码。第一,方面:

struct custom_space_facet: std::ctype<char> {
    custom_space_facet(const std::string& s): std::ctype<char>(get_table(s)) {}

    static const std::ctype_base::mask* get_table(std::string const &s) {
        static std::vector<std::ctype_base::mask> rc(table_size, std::ctype_base::mask());
        for (auto ch : s) rc[ch] = std::ctype_base::space;
        return &rc[0];
    }
};

struct decimal_coma_facet : std::numpunct<char> {
    char do_decimal_point() const { return ','; }
};

接下来,代码本身:

auto l1 = std::locale(std::locale(), new custom_space_facet(" \t[]"));
auto l2 = std::locale(std::locale(), new decimal_coma_facet);

auto locale = l1.combine<std::numpunct<char>>(l2);

std::stringstream input("[12,75082301 28,53644171   119,392771] [108,4213282 30,04183776 77,14237388]");
input.imbue(locale);

std::cout << std::setprecision(10);

double value;
while (input >> value)
   std::cout << value << "\n";

运行此功能将为您提供所需的双打:

12.75082301
28.53644171
119.392771
108.4213282
30.04183776
77.14237388