2015-01-25 2 views
0

Мой код работает как надо, но я нахожусь в поисках более элегантное решениеУплотнить этот фрагмент кода C++

В этом для петли, я разбора строки текста из файла с членами данных разделенный запятой. Это было сохранено в vector<str>str

файл в тексте:

bob,1,2,3 
sally,5,8,6 
joe,5,1,9 

Мне нужно хранить отдельно имя и 3 соответствующие значения в соответствующие отсеки в vector<student> s.

Любой способ конденсировать это?

for (string currLine : str) 
    { 
     int pos = 0; 
     int next = 0; 
     next = currLine.find (',', pos); 
     string name (currLine.substr (pos, next)); 

     pos = next + 1; 
     next = currLine.find (',', pos); 
     string expr (currLine.substr (pos, next)); 
     int a = atoi (expr.c_str()); 

     pos = next + 1; 
     next = currLine.find (',', pos); 
     expr = (currLine.substr (pos, next)); 
     int b = atoi (expr.c_str()); 

     pos = next + 1; 
     next = currLine.find (',', pos); 
     expr = (currLine.substr (pos, next)); 
     int c = atoi (expr.c_str()); 

     student s (name, a, b, c); //create student with extracted name and scores 

     vec.push_back (s); //now push this student onto the vector 
    }//end for() 
+0

Попробуйте использовать струнный поток. –

+0

Это просто альтернатива atoi(), правильно? Если theres больше для stringstream, чем я знаю – SSOPLIF

+1

Возможный дубликат [Как читать и анализировать CSV-файлы на C++?] (Http://stackoverflow.com/questions/1120140/how-can-i-read-and-parse- csv-files-in-c) – Barmar

ответ

0

Вы можете изменить пробельные классификацию для потока, ввести «поток экстрактор» (operator>>()), а также использовать std::istream_iterator<student> для вставки в вектор. Вот пример того, как может выглядеть ваша программа:

#include <iostream> 
#include <vector> 
#include <iterator> 

class student_fmt; 

struct student 
{ 
    student() = default; 
    student(std::string const& name, std::string const& a, 
      std::string const& b, std::string const& c) 
     : m_name(name) 
     , m_a(a) 
     , m_b(b) 
     , m_c(c) 
    { } 

    friend std::istream& operator>>(std::istream& is, student& s) 
    { 
     if (std::has_facet<student_fmt>(is.getloc())) 
     { 
      is >> s.m_name >> s.m_a >> s.m_b >> s.m_c; 
     } 
     return is; 
    } 

    void display() const 
    { 
     std::cout << m_name << m_a << " " << m_b << " " << m_c << '\n'; 
    } 
private: 
    std::string m_name, m_a, m_b, m_c; 
}; 

class student_fmt : public std::ctype<char> 
{ 
    static mask table[table_size]; 
public: 
    student_fmt(size_t refs = 0) : std::ctype<char>(table, false, refs) 
    { 
     table[static_cast<int>(',')] |= space; 
    } 
}; 

student_fmt::mask student_fmt::table[table_size]; 

int main() 
{ 
    std::cin.imbue(std::locale(std::cin.getloc(), new student_fmt)); 
    std::vector<student> v(std::istream_iterator<student>(std::cin), {}); 

    for (auto& c : v) 
     c.display(); 
} 
0

Попробуйте использовать оператор fstream и экстракт. Вы можете легко сохранить свой ввод в отдельные переменные.

#include <fstream> 

    . 
    . 
    . 

    // declare variables 
    fstream fin("fileName.txt", ios::in); 
    string name; 
    char comma; 
    int a, b, c; 

    // loop until the end of the file 
    while(!fin.eof()) 
     { 
     // get one line of data from the file 
     fin >> name >> comma >> a >> comma >> b >> comma >> c; 

     // add to your datatype 
     student s (name, a, b, c); 

     // push into your vector 
     vec.push_back (s); 
     } 
+0

это не удается, если счет имеет более одной цифры, также он не принимает числовое значение оценки, но код символа. – sled

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