2014-09-20 7 views
0

Я пытаюсь разобрать текстовый файл.Отформатированный текстовый текстовый файл

Формат:

  1. 6 пространства
  2. строка
  3. пробел + подчеркивание + строка
  4. запятой + подчеркивание + строка
  5. запятой + подчеркивание + строка

Вот пример: " house1 _rst1,_ab,_aaaa"

Этот код работает:

#include <iostream> 
#include <string> 
#include <fstream> 

using namespace std; 

int main() { 
    ifstream infile("test.txt"); 
    string line; 
    while (getline(infile, line)) { 
     string house, param1, param2, param3; 
     size_t posP1, posP2, posP3; 

     // trim leading whitespaces 
     while (isspace(line.at(0))) 
      line = line.substr(1,line.length() - 1); 

     posP1 = line.find(" _"); 
     house = line.substr(0, posP1); 

     posP2 = line.find(",_", posP1 + 2); 
     param1 = line.substr(posP1 + 2, posP2 - posP1 - 2); 

     posP3 = line.find(",_", posP2 + 2); 
     param2 = line.substr(posP2 + 2, posP3 - posP2 - 2); 

     param3 = line.substr(posP3 + 2, line.length() - 2); 

     cout << house << " : " << param1 << ", " << param2 + ", " << param3 << endl; 
    } 
    return 0; 
} 

я получить house1 : rst1, ab, aaaa, но я хотел бы улучшить код, используя что-то вроде stackoverflow.com/a/3555952/3029422, но я не знаю, как применить его к моему случаю, когда я пытаюсь:

ifstream infile("test.txt"); 
string line; 
while (getline(infile, line)) { 
    string house, param1, param2, param3; 

istringstream iss(line); 
    if (!(iss >> house >> param1 >> param2 >> param3)) 
     cout << "not the expected format" << endl; 
    else 
     cout << house << " : " << param1 << ", " << param2 + ", " << param3 << endl; 

Я получаю not the expected format

Как я могу читать каждую строку из файла непосредственно в переменные? Я выгляжу более чистым и легким для чтения таким образом.

+0

Парсинг по умолчанию работает только в том случае, если вещи разделены пробелами (пробелы). У вас есть поля, разделенные запятыми, и вам потребуется немного больше работы, чтобы вы это указали. – woolstar

ответ

1

Я считаю, что синтаксические разлочки, как это намного проще, используя streams, а не string обработки. Я часто использую std::istringstream, чтобы превратить строку, которую я прочитал в поток для синтаксического анализа.

Возможно, этот примерный код может быть вам полезен?

#include <string> 
#include <sstream> 
#include <iostream> 

int main() 
{ 
    std::string line = " house1 _rst1,_ab,_aaaa"; 

    std::string house, param1, param2, param3, skip; 

    std::istringstream iss(line); 

    iss >> house; 
    std::getline(iss, skip, '_'); 
    std::getline(iss, param1, ','); 
    std::getline(iss, skip, '_'); 
    std::getline(iss, param2, ','); 
    std::getline(iss, skip, '_'); 
    std::getline(iss, param3); 

    std::cout << house << " : " << param1 << ", " << param2 + ", " << param3 << '\n'; 
} 

EDIT:

Также вы можете сцепить поток вызовов вместе, чтобы сформировать одну все-encompasing линии анализатор, а так:

#include <fstream> 
#include <string> 
#include <iostream> 

int main() 
{ 
    std::ifstream infile("test.txt"); 

    std::string house, param1, param2, param3; 

    // this uses ignore() to skip over the '_' characters and std::getline() 
    // to read up to the ',' delimeters. 
    while(std::getline(std::getline(std::getline((infile >> house >> std::ws).ignore() 
     , param1, ',').ignore(), param2, ',').ignore(), param3)) 
    { 
     std::cout << house << " : " << param1 << ", " << param2 + ", " << param3 << '\n'; 
    } 
} 

Но это может быть трудно читать; о)

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