2015-04-25 2 views
0

у меня есть строковый объект, который является чем-то вроде:Разбор строки в C++ по нескольким разделителей

string test = " 
[3, 4, 8, 10, 10]\n[12]\n[12, 10,\n 20] 
" 

И я пытаюсь разобрать его в 3-х отдельных массивов, равных [3, 4, 8, 10, 10] , [12] и [12, 10, 20]. Я проанализировал целые числа, разделенные запятыми, в массив раньше, но как я могу разобрать этот синтаксис. К сожалению, у данных, которые у меня есть, может быть newlines mid array, иначе я бы использовал функцию getline (при чтении файла в строку) и просто игнорировал скобки.

Похоже, мне нужно сначала получить каждый массив в свою строку, ограниченную скобками, а затем разобрать каждый из них путем деления запятой на массив целых чисел. Будет ли это работать?

Если да, то как мне разделить строку по скобкам на ранее неизвестное количество других строк?

ответ

1

Если вы уже прочитали все это в строку, должно работать:

#include <iostream> 
#include <string> 

using namespace std; 

int main() { 
    string test = "[3, 4, 8, 10, 10]\n[12]\n[12, 10,\n 20]"; 
    size_t start = 0; // first position in the string 

    // find the first occurance of "]" 
    size_t pos = test.find("]"); 

    while (pos != string::npos) { 
    // move to position after "]" 
    // so it is included in substring 
    pos += 1; 

    // create a substring 
    string subStr = test.substr(start, pos-start); 

    // remove newlines from new string 
    size_t newLinePos = subStr.find("\n"); 
    while (newLinePos != string::npos) { 
     subStr.erase(newLinePos,1); 
     newLinePos = subStr.find("\n"); 
    } 

    // here is the substring, like: [12, 10, 20] 
    cout << "Substring: " << subStr << endl; 

    // update start position for next substring 
    start = pos; 
    // find next occurrance of "]" 
    pos = test.find("]", pos); 
    } 

} 
3

Вы можете использовать потоки и std::getline() для этого, как std::getline() принимает разделитель в качестве параметра:

int main() 
{ 
    std::string test = "[3, 4, 8, 10, 10]\n[12]\n[12, 10,\n 20]"; 

    // make data a stream (could be a std::ifstream) 
    std::istringstream iss(test); 

    // working vars 
    std::string skip, item; 

    // between square braces 
    // skip to the opening '[' then getline item to the closing ']' 
    while(std::getline(std::getline(iss, skip, '['), item, ']')) 
    { 
     // item = "3, 4, 8, 10, 10" 

     // store numbers in a vector (not array) 
     std::vector<int> v; 

     // convert item to a stream 
     std::istringstream iss(item); 

     // separated by commas 
     while(std::getline(iss, item, ',')) 
      v.push_back(std::stoi(item)); 

     // display the results 
     std::cout << "list:" << '\n'; 
     for(auto i: v) 
      std::cout << "\t" << i << '\n'; 
    } 
} 

Выход:

list: 
    3 
    4 
    8 
    10 
    10 
list: 
    12 
list: 
    12 
    10 
    20 
0

Один из способов приблизиться к этому - использовать функцию explode(). Реализации explode() разбивают строку на несколько строк на основе заданного разделителя. Это не самый эффективный метод, но он может сделать много интуитивного смысла.

См: Is there an equivalent in C++ of PHP's explode() function?

+1

Если он может, может быть, вы тоже ... – Potatoswatter

+0

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

+1

Вы не предлагали его реализовать, только чтобы найти что-то с поисковой системой. В любом случае, что угодно. – Potatoswatter

Смежные вопросы