2013-12-17 50 views
0

目前我想在字符讀入一類,看起來像這樣存儲文本文件轉換成一個類

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

}; 

我也有一個包含下列元素的矢量:

2A 
    Aorta_Ascendens 
    2 
    1.47 
    .164 
    4 
    53.4 
    2B 
    Aorta_Ascendens 
    2 
    1.44 
    .161 
    4 
    51.0 
    3A 

我想要將文本文件讀入每個部分,並且當前這是我的算法,可以連續讀取文本文件並分別添加每個部分。

int place = 0; 

     while (place != temp_data.size()){ 
      int counter = 0; 
      for (counter; counter <= 7; ++counter){ 
       istringstream is(temp_data[place + counter]); 

       if (counter == 0){ is >> a.segment; } 
       if (counter == 1){ is >> a.name; } 
       if (counter == 2){ is >> a.length; } 
       if (counter == 3){ is >> a.radius; } 
       if (counter == 4){ is >> a.wall_thickness; } 
       if (counter == 5){ is >> a.young_modulus; } 
       if (counter == 6){ is >> a.compliance; } 

      } 
      counter = counter - 1;  //since the next segment is at temp_data[7], must subtract one to have place = 7. 
      place = counter + place; 

      v.push_back(a); 
     } 

我碰到的問題是試圖找到一種方法來確保文本的正確部分進入對象的正確部分。對於前七行文本的對象應該是這樣的:

segment: 2A 
name: Aorta_Ascendens 
length: 2 
radius: 1.47 
wall_thickness: .164 
young modulus: 4 
compliance: 53.4 

這應該同樣的方法重複整個文本文件。 temp_data是一個包含需要添加到對象中的元素的向量,但我無法找到一種不斷循環遍歷向量並將元素放到正確位置的好方法。

我製作的算法有一個計數器和一個佔位符,計數器將循環遍歷矢量點,佔位符將保留第一個對象的數據成員的位置,在這種情況下爲段。在算法結束時,位置應該等於temp_data的大小並離開循環。但編譯和運行時遇到問題,它似乎將錯誤的元素放入錯誤的對象成員中。

任何想法?

回答

1

一個簡單,乾淨的方式來處理,這是寫一個自定義的流運算符:

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

    friend std::istream& operator>>(std::istream& is, data& d) 
    { 
     return is >> d.segment >> d.name >> d.length >> d.radius >> d.wall_thickness 
        >> d.young_modulus >> d.compliance; 
    } 
}; 

沒有temp_dataistringstreamcounter

要使用此:

data d; 
while (input_stream >> d) 
    v.push_back(d); 
if (input_stream.fail()) 
    ...print error/exit or whatver... 
else 
    ...use v... 

(有使用標準算法和back_inserter迭代器更具聲明的方式從流複製到向量,但恕我直言淺顯好)

0
  • 手冊方法

那麼你可以使用你的FILEFORMAT使用映射的一個比較經典的方法(也就是,如果你有訪問您的文件的規格(內容))。

你已經給你的文字應該是什麼樣子的完美的例子:

segment: 2A 
name: Aorta_Ascendens 
length: 2 
radius: 1.47 
wall_thickness: .164 
young modulus: 4 
compliance: 53.4 

什麼是與該格式的問題? 因此,它可以提供更好的靈活性(安全性),因爲您可以確定會員是您期望閱讀的內容。 你可以用分隔符分隔對象:

segment: 2A 
name: Aorta_Ascendens 
length: 2 
radius: 1.47 
wall_thickness: .164 
young modulus: 4 
compliance: 53.4 
**@** 
segment: 2B 
name: Aorta_Ascendens 
length: 3 
radius: 1.00 
wall_thickness: .164 
young modulus: 4 
compliance: 53.4 

使用ifstream.readlines()來獲得C++風格的字符串,這將幫助你分析使用find()功能的陣列(返回string::npos如果沒有找到)。
在parse()函數它涉及遍歷文件的行, 第一個,使用find尋找:字符,需要使用substr檢查哪些部件分配的值(以及如何解析,整數左側部分,枚舉?...)和另一個substr(稍加計算)(例如size - posfound)來選擇正確的部分,並將其放入您選擇的lexical_castboost::lexial_caststd::istringstream

  • 升壓方式

否則,您必須使用boost::serialization的選擇,這將讓你寫的只有一個超級簡單的函數讀取這種格式。 (參見附件)

  • 數據綁定(到XML,傑森,INI ...)

或更復雜的數據綁定框架,如碼合成XSD(的Xerces):
http://www.codesynthesis.com/products/xsd/

  • Python!

甚至更​​簡單,使用python。你只需要做eval()

PS:從文檔附件採取(與boost::serialization):

class gps_position 
{ 
private: 
    friend class boost::serialization::access; 
    // When the class Archive corresponds to an output archive, the 
    // & operator is defined similar to <<. Likewise, when the class Archive 
    // is a type of input archive the & operator is defined similar to >>. 
    template<class Archive> 
    void serialize(Archive & ar, const unsigned int version) 
    { 
     ar & degrees; 
     ar & minutes; 
     ar & seconds; 
    } 
    int degrees; 
    int minutes; 
    float seconds; 
public: 
    gps_position(){}; 
    gps_position(int d, int m, float s) : 
     degrees(d), minutes(m), seconds(s) 
    {} 
}; 

是不是很愚蠢的簡單?並保證工作。 (以及只要你用相同的序列化器編寫文件)。
http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/index.html

相關問題