I am working on removing sscanf()
calls from a C++ codebase and replacing them with the std::stringstream
implementation described here: https://www.quora.com/Is-there-a-C-alternative-to-sscanf . The relevant code is:
template<class Char>
class imatch
{
const Char* s;
public:
imatch(const Char* x) :s(x) {}
template<class Stream>
friend Stream& operator >> (Stream& st, const imatch& m)
{
std::basic_string<Char> x;
st >> x; //strip spaces, read chars up to space
if(x!=m.s) st.setstate(st.failbit); //set as "failure" a mismatch
return st;
}
};
Then in my codebase:
std::stringstream ss("value = 15"); //the input
int val=0;
ss >> imatch("value") >> imatch("=") >> val;
if(ss)
{ std::cout << "read value = " << val << std::endl; }
else
{ std::cout << "read failed" << std::endl; }
This uses class template argument deduction in the constructor calls. It works great...in C++17. The problem is that this code needs to compile all the way back to RHEL6, which only supports -std=c++0x
at best (a subset of C++11).
What is the most succinct way to write and use this class such that users can easily port their sscanf()
calls to use it, without access to C++17?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…