Разбор строк в разные типы с разными разделителями

0

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

struct Artery{
string segment; string name;
double length; double radius; double wall_thickness;
double young_modulus; double compliance;

Artery(string seg, string n, double l, double r, double w, double y, double c)
    : segment(seg), name(n), length(l), radius(r), wall_thickness(w), young_modulus(y), compliance(c){}
};

Данные будут в формате:

(Сегмент, имя, длина, радиус, толщина стенки, модуль юниоров, соответствие)
(2А, Aorta_Ascendens, 2, 1.47,.164, 4, 53.4)
(2B, Aorta_Ascendens, 2, 1.44,.161, 4, 51.0)
(3А, Arcus_Aorta, 2, 1.12,.132, 4, 29.6)

Я на самом деле просто новичок на языке C++ (сейчас на самом деле беру курс обучения по предмету), и мы не рассматривали низкоуровневое программирование указателями, и я знаю, что обычно используется для анализа этого Такие вещи. Могу ли я помочь с этим? Я действительно не знаю, как это сделать.

Ниже приведено то, что я в настоящее время испытываю при попытке проанализировать файл. В конце концов я хотел, чтобы в конце появился вектор Артерии, который послужит основой для доступа к информации.

void read_data(vector<Artery>& v, ifstream& ifs){
//reads and seperates file for arterial data (currently from the westerhoff model)
vector<string> data_string;
while (!ifs.eof){
    string data_set = " ";
    getline(ifs, data_set);
    data_string.push_back(data_set);
}

for (int i = 0; i < data_string.size(); ++i){
    string seg; string n;
    double l; double r; double w; double y; double c;

    istringstream iss(data_string[i]);




}

}

Напомним: мне нужна помощь в разборе файла с указанным выше форматом, а затем преобразование этого формата в артерию. Я хочу затем скомпилировать их в вектор Артерии, чтобы потом получить к ним доступ.

Спасибо,

Zav

  • 0
    Запятые являются частью строк примера? То есть ваши значения данных разделены запятыми (CSV)? И скобки начинаются и заканчиваются в каждой строке?
Теги:
string
vector
parsing

1 ответ

0
Лучший ответ

Есть много способов сделать это.

Предполагая, что ваш поток, ifs уже инициализирован и is_open (вы уже выполнили проверку потока, тогда вы выполняете все операции за один раз (сокращение времени выполнения по крайней мере в два раза по сравнению с вашей версией):

void read_data(std::vector<Artery>& v, std::ifstream ifs) {
    std::vector<std::string> data_strings;

    std::string temp;

    //read the file by lines
    while(std::getline(ifs, temp)) {
        //store the line (included for completeness)
        data_strings.push_back(temp);

        //as you didn't state if your lines began and ended with parentheses
        //I opted to cover removal of them:
        size_t begin = temp.find("(");//as there is only 1
        size_t end = temp.find(")");//as there is only 1

        temp = temp.substr(begin+1, end-1);

        std::istringstream iss(temp);
        Artery artery;

        int col = 1;//the current column

        //here we're going to use the stringstream to tokenize the string by commas
        //using std::getline
        while (std::getline(iss, temp, ',')) {
            std::istringstream is(temp);//this is another string stream initialized to the token (which may or may not be a string)
            //determine which artery property to modify based on the column number
            switch(col) {
                case 1:
                    is >> artery.segment;
                    break;
                case 2:
                    is >> artery.name;
                    break;
                case 3:
                    is >> artery.length;
                    break;
                case 4:
                    is >> artery.radius;
                    break;
                case 5:
                    is >> artery.wall_thickness;
                    break;
                case 6:
                    is >> artery.young_modulus;
                    break;
                case 7:
                    is >> artery.compliance;
                    break;
                default:
                    std::cerr << "Invalid column!\n";
            }
            ++col;
        }

        //now the artery has been correctly initialized, we can store it:
        v.push_back(artery);
    }
}

Вы заметите, что эта версия не использует Artery вами Artery конструктор. Он мог бы использоваться, но из того, как вы определили Artery, он очень напоминает POD (тип Plain-Old-Data); следовательно, я рассматривал его в этом решении.

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

ЗАМЕТКА:

Мое использование оператора извлечения строки (>>) не проверяет правильное назначение. Но, поскольку это наивный пример, это то, что вы можете сделать для себя.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню