I wrote a bit of code that can read in string and character literals. Like normal stream reads, if it gets invalid data it sets the badbit of the stream. This should work for all types of streams, including wide streams. Stick this bit in a new header:
#include <iostream>
#include <string>
#include <array>
#include <cstring>
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&sliteral)[N]) {
std::array<e, N-1> buffer; //get buffer
in >> buffer[0]; //skips whitespace
if (N>2)
in.read(&buffer[1], N-2); //read the rest
if (strncmp(&buffer[0], sliteral, N-1)) //if it failed
in.setstate(in.rdstate() | std::ios::failbit); //set the state
return in;
}
template<class e, class t>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& cliteral) {
e buffer; //get buffer
in >> buffer; //read data
if (buffer != cliteral) //if it failed
in.setstate(in.rdstate() | std::ios::failbit); //set the state
return in;
}
//redirect mutable char arrays to their normal function
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
return std::operator>>(in, carray);
}
And it will make input characters very easy:
std::istringstream input;
double val1, val2;
if (input >>'('>>val1>>','>>val2>>')') //less chars than scanf I think
{
// got them!
}
PROOF OF CONCEPT. Now you can cin
string and character literals, and if the input is not an exact match, it acts just like any other type that failed to input correctly. Note that this only matches whitespace in string literals that aren't the first character. It's only four functions, all of which are brain-dead simple.
EDIT
Parsing with streams is a bad idea. Use a regex.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…