2009-12-26 59 views
1

我希望能夠使用std :: stringstream或boost :: lexical_cast等標準技術來序列化我的C++類。例如,如果我有一個Point對象(2,4),那麼我想將它序列化爲「(2,4)」,並且也能夠從這個字符串構造一個Point對象。如何使一個C++類與stringstream對象兼容?

我已經有一些代碼,但有一些問題。指向字符串的作品,但有時輸入不會完全從流中讀取。字符串到點轉換導致bad_cast異常。

class Point 
{ 
public: 
    Point() : mX(0), mY(0) {} 
    Point(int x, int y) : mX(x), mY(y){} 
    int x() const { return mX; } 
    int y() const { return mY; } 
private: 
    int mX, mY; 
}; 

std::istream& operator>>(std::istream& str, Point & outPoint) 
{ 
    std::string text; 
    str >> text; // doesn't always read the entire text 
    int x(0), y(0); 
    sscanf(text.c_str(), "(%d, %d)", &x, &y); 
    outPoint = Point(x, y); 
    return str; 
} 

std::ostream& operator<<(std::ostream& str, const Point & inPoint) 
{ 
    str << "(" << inPoint.x() << ", " << inPoint.y() << ")"; 
    return str; 
} 

int main() 
{ 
    Point p(12, 14);  
    std::string ps = boost::lexical_cast<std::string>(p); // "(12, 14)" => OK  
    Point p2 = boost::lexical_cast<Point>(ps); // throws bad_cast exception! 
    return 0; 
} 

我該如何解決這些問題?

回答

5

要閱讀一整行,你可以使用函數std::getline

std::string text; 
getline(str, text); 
+0

謝謝,這個簡單的修改了我的代碼! – StackedCrooked 2009-12-26 22:25:08

3

AFAIK,str >> text;將從流中讀取單個「單詞」。

解析很難。怎麼樣這樣(未經測試):

char paren; 
str >> paren; 
if (paren != '(') throw ParseError(); // or something... 

int x, y; 
char comma; 
str >> x >> comma >> y; 
if (comma != ',') throw ParseError(); 

str >> paren; 
if (paren != ')') throw ParseError(); 
+0

是,提取操作由空格分隔。 – joshperry 2009-12-26 20:25:43

3

既然你已經使用提升,你爲什麼不看提高serialization

序列化格式應該獨立於序列化的對象,boost的lib可以很好地處理它。

相關問題