arrays - User input to matrix in C++ -
i have trouble read in input user , convert them matrix calculation. example, input = {1 2 3 / 4 5 6}
, program should read in matrix in form of
1 2 3 4 5 6
which have 3 cols , 2 rows. got far not seem work:
input.replace(input.begin(), input.end(), '/', ' '); stringstream ss(input); string token; while (getline(ss, token, ' ')) { (int = 0; < row; i++) { (int j = 0; j < col; j++) { int tok = atoi(token.c_str()); (*matrix).setelement(i, j, tok); } } }
so i'm trying break input token , store them matrix using setelement function take number of row, column , variable user want store. wrong code variable of tok
doesnt seem change , keep stuck in 0
. assuming row , col knows.
thanks help.
although many simple ways exist solve specific problem (and other answer have various suggestions) let me try give more general view of problem of "formatted input".
there 3 kind of problems, here:
- at low level youi have string number conversion
- at higer level have parse composite format (understanding rows , line separation)
- finally have understand size of compound (how many rows , cols?)
this 3 things not independent , last needed know how store elements (how size matrix?)
finally there 4th problem (that spread other other 3): if input "wrong".
these kind of problem typically afforded in 2 opposite ways:
- read data come, recognize if format matched, , dynamically grow data structure have contain them or...
- read data once (textual form) analyze text figure out how many elements has, isolate "chunks" , conversions.
point 2. requires string manipulations, requires ability know how input long (what happens if 1 of separating spaces new-line? idea got getline
fails in cases)
point 1 requires matrix
class capable grow read or temporary dynamic structure (like , std
container) in yo ucan place read before sending appropriate place.
since don't know how matrix works, let me keep temporary vector , counters store lines.
#include <vector> #include <iostream> #include <cassert> class readmatrix { std::vector<int> data; //storage size_t rows, cols; //the counted rows , columns size_t col; //the counting cols in current row matrix& mtx; //refer thematrix has read public: // keep reference destination readmatrix(matrix& m) :data(), rows(), cols(), cols(), mtx(m) {} // make class istream-->istream functors let usable stream // maniopulator: input >> readmatrix(yourmatrix) std::istream& operator()(std::istream& s) { if(s) //if can read { char c=0: s >> c; //get char. if(c!='{') //not open brace { s.setstate(s.failbit); return s; } //report format failure while(s) //loop on rows (will break win '}' found) { col=0; while(s) //loop on cols (will break when '/' or '}' found) { c=0; s >> c; if(c=='/' || c=='}') //row finished? { if(!cols) cols=col; //got first row length else if(cols != col) //it appears row have different length { s.setstate(s.failbit); return s; } //report format failure if(c!='/') s.unget(); //push char later break; //row finished } s.unget(); //pushthe "not /" char int x; s >> x; //get integer if(!s) return s; //failed read integer! ++col; data.push_back(x); //save read data } ++rows; //got entire row c=0; s >> c; if(c == '}') break; //finished rows else s.unget(); //push char: next row begin } } //now, if read successful, // can dispatch data final destination if(s) { mtx.setsize(rows,cols); // assume can set matrix size way auto = data.begin(); //will scan inner vector for(size_t r=0; r<rows; ++r) for(size_t c=0; c<cols; ++c, ++it) mtx(r,c) = *it; //place data assert(it == data.end()); //this must true if counting have gone right } return s; } };
now can read matrix as
input >> readmatrix(matrix);
you notice @ point there recurring patterns in code: typical in one-pass parses, , patterns can grouped form sub-parsers. if generically -in fact- rewrite boost::spirit
.
of course adaption can done depending on how matrix works (has fixed sizes??), or if rows sizes don't match (partial column filling ??)
you can add formatted input operator like
std::istream& operator>>(std::istream& s, matrix& m) { return s >> readmatrix(m); }
so can do
input >> matrix;
Comments
Post a Comment