2011-12-22 131 views
0

我有一些問題,我的操作>>C++ istream的操作>>

istream& operator>> (istream& is, Matrix& M) { 

    char first; 

    is>>first; 


    for(int i = 0;i<M.rows();i++) { 

     for(int j = 0;j<M.cols();j++) { 

      is>>M[i][j]; 
      cout<<M[i][j]; 

     } 

     is>>first; 

    } 

    return is; 
} 

我想將istream的運營商的大小,因爲我想改變的for循環,使他們不依賴於在ie中發送的矩陣是你發送一個大小爲1的矩陣和流[1 2 3 4; 4 5 6 7; 1 2 3 4],然後構造一個大小爲(3 * 4)的新矩陣。以便我可以使用賦值運算符將其賦值給矩陣M.

換句話說,流的格式爲"[ 1 2 3; 2 3 4; 4 5 6]";意味着新的一排。 我想知道有多少行和列。

回答

0

問題是流提取操作符需要一個可以修改的已經構建的對象。你必須調整你的矩陣類,以便它可以動態調整大小。

0

不可能確定「istream運算符的大小」,因爲它是,流,當你讀第一個矩陣元素時,沒有人能保證最後一個元素已經存在。您應該首先閱讀整個字符串,然後解析它並提取有關輸入矩陣大小的信息。之後,您可以通過stringstream提供此字符串來使用您的代碼。當然,你必須能夠動態地改變矩陣的大小。

2

你可以得到所有這樣的行:

vector<string> rows; 
string line; 

is.ignore(INT_MAX, '['); // ignores all characters until it passes a [ 

while (std::getline(is, line, ';')) 
    rows.push_back(line); // put each row in rows 

rows.back().erase(rows.back().find(']')); // erase the ending ] 

現在,你必須在rows每一行字符串,然後

for (size_t i = 0; i < rows.size(); ++i) { 
    vector<int> items; 
    istringstream strstm(rows[i]); 

    std::copy(istream_iterator<int>(strstm), istream_iterator<int>(), back_inserter(items)); 

    // now items is full of the entries, resize the matrix to hold items.size() 
    // many items and insert each one into it, or whatever 
} 
+0

我得到這個錯誤:變量「的std :: istringstream strstm」有初始但 – shizzle 2011-12-22 09:25:06

+0

不完全類型@ shizzle:你需要'#include '。 – 2011-12-22 12:19:08

1

首先,當然,你需要指定的東西比你更嚴格的是 。你應該怎麼做,如"[ 11 12 13; 21 22; 31 32 33 ]",例如:插入一個0.0爲缺失值,或設置 failbit

除此之外,使用std::vector收集輸入將使事情變得更容易 位。類似下面的,例如:

template< typename T > 
char getRow(std::istream& source, std::vector<T>& dest) 
{ 
    dest.clear(); 
    char separator; 
    source >> separator; 
    while (source && separator != ';' && separator != ']') { 
     source.unget(); 
     T tmp; 
     source >> tmp; 
     if (source) { 
      dest.push_back(tmp); 
      source >> separator; 
     } 
    } 
    if (source && dest.empty()) { 
     dest.setstate(std::ios_base::failbit); 
    } 
    return source ? separator : '\0'; 
} 

template< typename T > 
char getFirstRow(std::istream& source, 
        std::vector<std::vector<T> >& dest) 
{ 
    dest.clear(); 
    std::vector<T> row; 
    char separator = getRow(source, row); 
    if (source) { 
     if (row.empty()) { 
      dest.setstate(std::ios_base::failbit); 
     } else { 
      dest.push_back(row); 
     } 
    } 
    return source ? separator : '\0'; 
} 

template< typename T > 
char getFollowingRow(std::istream& source, 
       std::vector<std::vector<T> >& dest) 
{ 
    std::vector<T> row; 
    char separator = getRow(source, row); 
    if (source) { 
     if (row.size() != dest.front().size()) { 
      dest.setstate(std::ios_base::failbit) ; 
     } else { 
      dest.push_back(row); 
     } 
    } 
    return source ? separator : '\0'; 
} 

template< typename T > 
std::istream& 
operator>>(std::istream& source, Matrix<T>& dest) 
{ 
    char separator; 
    source >> separator; 
    if (separator != '[') { 
     source.setstate(std::ios_base::failbit); 
    } else { 
     std::vector<std::vector<T> > results; 
     separator = getFirstRow(source, results); 
     while (separator == ';') { 
      separator = getFollowingRow(source, results); 
     } 
     if (separator != ']') { 
      source.setstate(std::ios_base::failbit); 
     } 
     if (source) { 
      dest.assign(results); 
     } 
    } 
    return source; 
} 

當然,這意味着Matrix<T>::assign功能必須能夠 設定的尺寸。要使用,Matrix<T>需要一個默認的 構造函數,這可能會「推遲」實際構造,直到 Matrix<T>::assign

另外:由於iostream中的錯誤報告有限的可能性 ,我們在上述方面受到某種程度的限制。特別是,我們真的想要 區分諸如"[11 12 13; 21"之類的輸入和什麼都沒有(文件條件的真實結束 )。但是我們試圖在"21" 之後閱讀分隔符將會設置爲eofbit,並且我們無能爲力。 (實際上, 我們可以創建一個新的狀態字,使用std::ios_base::xalloc(), 如果設置它,當且僅當的'['在開始讀取失敗, eofbit集。但是這需要檢查 非常不規範的方式對於客戶端代碼中的錯誤,這又會造成維護問題的層出不窮 。)

最後,兩個元評論:如果這看起來很複雜......它是。輸入 幾乎總是複雜的,因爲你必須檢查所有各種錯誤 條件。其次,注意使用功能 保持每個單獨的操作(有點)簡單。這是初學者經常 錯誤不會打破下來這樣—它 幾乎總是編程差,例如,有一個 函數嵌套循環,像 Matrix應用數學算法的事情時除外。在這種情況下,解析不是一種數學算法,並且您想要將每行的處理與總體處理分開;在這種情況下,將第一行 的處理與其他處理分開也是有用的,因爲錯誤情況是不同的。 (第一行 可以有任意長度大於0,後來行必須具有相同的長度 與前行。)