2015-10-17 3 views
0

Я пытаюсь преобразовать строку в double, которая также содержит нецифровые символы. Мне было интересно, есть ли общее решение для этого, вместо того, чтобы найти индекс каждого нечислового символа в строке и удалить их по одному. (Что-то вроде atof())Преобразование части нечисловой строки в double

Например, вот моя ломаная линия (2 векторов координат):

«[12,75082301 28,53644171 119,392771] [108,4213282 30,04183776 77, 14237388] " (разделенный \ т и doublequotes включены в строке)

Я расщепляется Tindo строки массива

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

и в моей первой колонке есть: " [12,75082301

И в моей третьей колонке есть: 119,392771]

Есть простой способ, чтобы преобразовать строку в thoose дважды с тем же способом?

(И последующий вопрос: если есть 2 '\ t' directli рядом друг с другом, с StringSplitOption :: RemoveEmptyEntries, я должен пропустить пустую запись, но, похоже, это не работает для меня ... Идея?)

+0

https://msdn.microsoft.com/en -us/library/hs600312% 28v = vs.110% 29.aspx –

+0

Вы просто говорите об удалении квадратных скобок, не так ли? Эти запятые выглядят так, будто они предназначены для разделения фракций. (Я упоминаю это, потому что англоязычные страны используют период, и не все знают, что многие другие культуры используют запятую.) – Wyzard

+0

О да, извините, я забыл. Запятые действительно разделители! – Razero

ответ

0

Если ваши «нечисловые» символы могут появляться в любом месте строки (то есть в середине вашего номера «1,123 [456»), вы не можете избежать предварительной обработки строки и ее удаления. К счастью, вы можете сделать это за один проход, используя std::remove_if из std::copy_if алгоритмов.

Однако, если ваши «нечисловые» символы появляются только в начале или в конце строки, вы можете обрабатывать их как пробелы и «разделять» свою строку правильно, используя stringstream с настраиваемой локалью. Определите грань, которая будет обрабатывать [, ] и \t в качестве пробелов, и вы хорошо пойдете. Выполнение этого также позаботится о вашей второй проблеме - несколько смежных \t символов.

В дополнение к этому вы можете определить другую грань, которая будет обрабатывать , в виде десятичной точки. Объедините его с предыдущим, и вы можете прочитать double s непосредственно из исходной строки.

Вот код, который делает все это. Во-первых, фасеты:

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 
Смежные вопросы