Assume that I have an input as follows:
N (X_1,Y_1) (X_2,Y_2) .... (X_N, Y_N)
where N, X_i and Y_i are integers.
An example:
2 (55,1) (521,7)
To read this, I can do something like this(assume all variables are defined, etc.):
fscanf(fin,"%d ",&N);
for (int i = 0; i < N; i++)
fscanf(fin,"(%d,%d) ", &X[i], &Y[i]);
The question is, how can I do this easily using ifstream. I can get string's, and then I can get rid of nondigits and using stringstream I can get two numbers but this seems a bit cumbersome. Is there an easier, more elegant way?
Thanks
int n, x, y;
char c;
if (is >> n)
for (int i = 0; i < n; ++i)
if (is >> c && c == '(' &&
is >> x &&
is >> c && c == ',' &&
is >> y &&
is >> c && c == ')')
{
X[i] = x;
Y[i] = y;
}
else
throw std::runtime_error("invalid inputs");
You can simplify the all-important inner if
condition above to...
is >> chlit('(') >> x >> chlit(',') >> y >> chlit(')')
...with a simple support type for consuming a specific character:
struct chlit
{
chlit(char c) : c_(c) { }
char c_;
};
inline std::istream& operator>>(std::istream& is, chlit x)
{
char c;
if (is >> c && c != x.c_)
is.setstate(std::iostream::failbit);
return is;
}
See a complete program illustrating this on ideone here.
An old post of mine did something similar for consuming specific strings. (The above chlit
could be a template, but chlit<','>()
is ugly to read and write - I'd rather trust the compiler).