使用不同的分隔符将字符串解析为不同的类型

时间:2013-11-03 04:50:27

标签: c++ string parsing vector

这实际上是我第一次使用这个网站:通常我能够找到上一篇文章的解决方案,但这次我无济于事。无论如何,我的问题是我试图解析包含逗号和括号的文件。它还包含我需要从字符串更改为double的字符串和双精度数,因此我可以使用数据。我制作了一个存储数据的结构。

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){}
};

数据格式如下:

(段,名称,长度,半径,壁厚,杨氏模量,合规性)
(2A,Aorta_Ascendens,2,1.47,.164,4,53.4)
(2B,Aorta_Ascendens,2,1.44,.161,4,51.0)
(3A,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]);




}

}

回顾一下:我需要帮助解析具有上述格式的文件,然后将该格式转换为Artery。我想将它们编译成一个Artery向量,以便以后可以访问它们。

谢谢,

ZAV

1 个答案:

答案 0 :(得分: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,它非常类似于POD(普通旧数据类型);因此,我在这个解决方案中对待它。

另外,由于我不确定括号是否是每个构成线的一部分,我已经通过删除它们来对待它们。 (当然,如果您的数据不包含这些,您可以轻松删除处理该删除的代码。)

注:

我对字符串流提取运算符(>>)的使用不会检查是否正确分配。但是,因为这是一个简单的例子,这是你可以为自己做的事情。