Skip to content

Instantly share code, notes, and snippets.

@dgodfrey206
Last active December 28, 2015 09:09
Show Gist options
  • Save dgodfrey206/7476217 to your computer and use it in GitHub Desktop.
Save dgodfrey206/7476217 to your computer and use it in GitHub Desktop.
Getting key value pairs from a file.
#include <iostream>
#include <limits>
#include <string>
#include <fstream>
namespace utility
{
class stream_ok
{
public:
stream_ok(std::ios& str) : ios(str) { }
bool okay()
{
err = ios.rdstate();
// check the stream state
try
{
// do exception handling
} catch(...) { }
return ios;
}
protected:
std::basic_ios<char>& ios;
std::ios_base::iostate err;
};
template <class Facet>
struct erasable_facet : Facet
{
template<typename... Args>
erasable_facet(Args&&... args) : Facet(args...) { }
~erasable_facet() { }
};
static int key() { static int i = std::ios_base::xalloc(); return i; }
static int value() { static int i = std::ios_base::xalloc(); return i; }
}
class read_parsed_line : public utility::stream_ok
{
public:
read_parsed_line(std::istream& _is)
: stream_ok(_is), is(_is)
{ }
void scan_input();
private:
std::istream& is;
utility::erasable_facet<std::ctype<char>> ctype;
utility::erasable_facet<std::num_get<char, std::string::const_iterator>> numget;
bool valid(long l)
{
return std::numeric_limits<int>::min() <= l &&
std::numeric_limits<int>::max() >= l;
}
void scan_is(std::string& result)
{
result = ctype.scan_is(std::ctype_base::digit,
&result.front(), &result.back());
}
};
void read_parsed_line::scan_input()
{
std::string result;
result.assign(std::istreambuf_iterator<char>(is),
std::istreambuf_iterator<char>());
long l;
scan_is(result);
numget.get(result.begin(), result.end(), ios, err, l);
result.erase(result.begin());
if (!(valid(l) && okay()))
return;
else
is.iword(utility::key()) = l;
scan_is(result);
numget.get(result.begin(), result.end(), ios, err, l);
if (!(valid(l) && okay()))
return;
else
is.iword(utility::value()) = l;
}
struct S { };
std::ostream& operator <<(std::ostream& os, const S &)
{
static std::ifstream is("in.txt");
std::istream::sentry s(is);
if (s)
{
read_parsed_line rpl(is);
rpl.scan_input();
int key = is.iword(utility::key());
int value = is.iword(utility::value());
os << key << ", " << value << '\n';
}
return os;
}
int main()
{
S s;
out << s;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment