    #include <iostream>
    #include <string>
    #include <map>
    #include <iomanip>
    #include <fstream>

    using namespace std;

    // your structure
    struct person
    {
      string name, pass, role, mail;
    };

    // the tokens your format is using
    enum class token : char
    {
      lb = '{',
      rb = '}',
      sc = ':',
      comma = ',',
      str,
      end
    };

    token tk; // current token
    string str; // if the current token is token::str, str is its value

    // get_token breaks the input stream into tokens - this is the lexer, or tokenizer, or scanner
    token get_token(istream& is)
    {
      char c;
      if (!(is >> c))
        return tk = token::end;
      switch (c)
      {
      case '{':
      case '}':
      case ':':
      case ',':
        return tk = token(c);
      case '"':
        is.unget();
        is >> quoted(str);
        return tk = token::str;
      default: throw "unexpected char";
      }
    }

    // throws if the current token is not the expected one
    void expect(istream& is, token expected, const char* error)
    {
      if (tk != expected)
        throw error;
      get_token(is);
    }

    // throws if the current token is not a string
    string expect_str(istream& is, const char* error)
    {
      if (tk != token::str)
        throw error;
      string s = str;
      get_token(is);
      return s;
    }

    // the actual parser; it extracts the tokens one by oneand compares them with the expected order.
    // if the order is not what it expects, it throws an exception.
    void read(istream& is, person& p)
    {
      get_token(is); // prepare the first token

      expect(is, token::lb, "'{' expected");

      map<string, string> m; // key/values storage
      while (tk == token::str)
      {
        string k = expect_str(is, "key expected");
        expect(is, token::sc, "':' expected");
        string v = expect_str(is, "value expected");

        if (m.find(k) == m.end())
          m[k] = v;
        else
          throw "duplicated key";

        if (tk == token::comma)
          get_token(is);
        else
          break; // end of of key/value pairs
      }

      expect(is, token::rb, "'}' expected");
      expect(is, token::end, "eof expected");

      // check the size of m & the keys & copy from m to p
      // ...
    }

    int main()
    {
      try
      {
        person p;
        read(cin, p);
      }
      catch (const char* e)
      {
        cout << e;
      }
    }
