首先,當然,你需要指定的東西比你更嚴格的是 。你應該怎麼做,如"[ 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,後來行必須具有相同的長度 與前行。)
我得到這個錯誤:變量「的std :: istringstream strstm」有初始但 – shizzle 2011-12-22 09:25:06
不完全類型@ shizzle:你需要'#include'。 –
2011-12-22 12:19:08