2015-09-13 2 views
0

поэтому я получил дюжину строк, которые я загружаю, пример ниже, который мне нужно разобрать.Элегантное решение для синтаксического анализа строк

"036 AUD Австралия и 1 4,713831 4,728015 4,742199"

"Vel. Britanija 826 GBP 1 10,300331 10,331325 10,362319"

Так что моя первая идея была подсчитывать вручную, где номер, который мне нужен (второй, 4,728015 или 10,331325 в экзаменах) и получить подстроку. (52,8) Но тогда я понял, что немногие из строк, которые обрабатываются, имеют> 9 число в нем, так что мне понадобится подстрока (51,9) для этого случая, поэтому я не могу это сделать

Вторая идея состояла в том, чтобы сохранить все число, например, символы в vecto r, а затем получить вектор [4] и сохранить его в отдельную переменную.

И третий - просто закольтать строку, пока я не расположил себя после 5-й группы пространств, а затем подстрою ее.

Просто ищите информацию о том, что было бы «лучшим».

+0

введите подстроки, разделенные пробелами, используя getline. слияние ранних, пока у вас не будет 7. use group 5 – sp2danny

+1

Формат данных затрудняет * элегантное * решение, тем более что в первом поле допускаются пробелы. Я предлагаю читать строку текста и искать первый символ без цифр; который определяет содержание первого поля. Остальные поля можно извлечь, используя 'std :: istringstream' и' operator >> '. –

+0

Вид новичка здесь, могу я беспокоить вас для примера кода? – puernos

ответ

2

Проблема

является то, что мы можем иметь несколько слов в начале строки. То есть первый элемент может содержать пробелы.

Раствор

Начать с конца строки, где мы стабильны.

Разделить струну вверх в пространстве. Начните подсчет с конца и выберите предыдущий элемент.

Решение 1: алгоритмы подталкивания строковые

#include <string> 
#include <vector> 
#include <boost/algorithm/string.hpp> 
using namespace std; 
using namespace boost; 

string extractstring(string & fullstring) 
{ 
    vector<string> vs; 
    split(vs, fullstring); 
    return vs[vs.size() - 2]; 
} 

Раствор 2: QString (от Qt рамочные)

#include <QString> 
QString extractstring(QString & fullstring) 
{ 
    QStringlist sl = fullstring.split(" "); 
    return sl[vs.size() - 2]; 
} 

Раствор 3: STL только

#include <iostream> 
#include <string> 
#include <sstream> 
#include <algorithm> 
#include <iterator> 

using namespace std; 

string extractstring(string & fullstring) 
{ 
    istringstream iss(fullstring); 
    vector<string> elements; 
    copy(istream_iterator<string>(iss), 
     istream_iterator<string>(), 
     back_inserter(elements)); 
    return elements[elements.size() - 2]; 
} 

Другие решения: регулярное выражение, C-указатель акробатический.

Update:

Я бы не использовать sscanf решения, основанные, потому что это может быть трудно идентифицировать несколько слов в начале строки.

1

Я считаю, что вы можете сделать это с помощью одной строки, используя sscanf?

http://www.cplusplus.com/reference/cstdio/sscanf/

Например (http://ideone.com/e2cCT9):

char *str = "Australija 4,713831 4,728015 4,742199"; 
char tmp[255]; 
int a,b,c,d; 
sscanf(str, "%*[^0-9] %d,%d %d,%d", &a, &b, &c, &d); 

printf("Parsed values: %d %d %d %d\n",a,b,c,d); 
+0

Ну, я не уверен, что я не могу сказать функции, чтобы точно выбрать второе десятичное число из строки. – puernos

+0

@puernos, пожалуйста, уточните, как вы хотите разобрать строку и прочитать doc – Elalfer

+0

любым способом, который это работает, Мне просто нужно получить второе число в отдельной переменной, поэтому я могу сохранить его на карте. – puernos

0

Барьер является то, что первое поле разрешено иметь пробелы, но остальные поля разделены пробелами.

Это не может быть элегантным, но концепция должна работать:

std::string text_line; 
getline(my_file, text_line); 
std::string::size_type field_1_start; 
const unsigned int text_length = text_line.length(); 
for (field_1_start = 0; field_1_start < text_length; ++field_1_start) 
{ 
    if (is_digit(text_line[field_1_start]) 
    { 
    break; 
    } 
} 
if (field_1_start < text_length) 
{ 
    std::string remaining_text = text_line.substr(field_1_start, text_length - field_1_start); 
    std::istringstream input_data(remaining_text); 
    int field_1; 
    std::string field2; 
    input_data >> field_1; 
    input_data >> field_2; 
    //... 
} 
Смежные вопросы