fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <map>
  4. #include <iomanip>
  5. #include <fstream>
  6.  
  7. using namespace std;
  8.  
  9. // your structure
  10. struct person
  11. {
  12. string name, pass, role, mail;
  13. };
  14.  
  15. // the tokens your format is using
  16. enum class token : char
  17. {
  18. lb = '{',
  19. rb = '}',
  20. sc = ':',
  21. comma = ',',
  22. str,
  23. end
  24. };
  25.  
  26. token tk; // current token
  27. string str; // if the current token is token::str, str is its value
  28.  
  29. // get_token breaks the input stream into tokens - this is the lexer, or tokenizer, or scanner
  30. token get_token(istream& is)
  31. {
  32. char c;
  33. if (!(is >> c))
  34. return tk = token::end;
  35. switch (c)
  36. {
  37. case '{':
  38. case '}':
  39. case ':':
  40. case ',':
  41. return tk = token(c);
  42. case '"':
  43. is.unget();
  44. is >> quoted(str);
  45. return tk = token::str;
  46. default: throw "unexpected char";
  47. }
  48. }
  49.  
  50. // throws if the current token is not the expected one
  51. void expect(istream& is, token expected, const char* error)
  52. {
  53. if (tk != expected)
  54. throw error;
  55. get_token(is);
  56. }
  57.  
  58. // throws if the current token is not a string
  59. string expect_str(istream& is, const char* error)
  60. {
  61. if (tk != token::str)
  62. throw error;
  63. string s = str;
  64. get_token(is);
  65. return s;
  66. }
  67.  
  68. // the actual parser; it extracts the tokens one by oneand compares them with the expected order.
  69. // if the order is not what it expects, it throws an exception.
  70. void read(istream& is, person& p)
  71. {
  72. get_token(is); // prepare the first token
  73.  
  74. expect(is, token::lb, "'{' expected");
  75.  
  76. map<string, string> m; // key/values storage
  77. while (tk == token::str)
  78. {
  79. string k = expect_str(is, "key expected");
  80. expect(is, token::sc, "':' expected");
  81. string v = expect_str(is, "value expected");
  82.  
  83. if (m.find(k) == m.end())
  84. m[k] = v;
  85. else
  86. throw "duplicated key";
  87.  
  88. if (tk == token::comma)
  89. get_token(is);
  90. else
  91. break; // end of of key/value pairs
  92. }
  93.  
  94. expect(is, token::rb, "'}' expected");
  95. expect(is, token::end, "eof expected");
  96.  
  97. // check the size of m & the keys & copy from m to p
  98. // ...
  99. }
  100.  
  101. int main()
  102. {
  103. try
  104. {
  105. person p;
  106. read(cin, p);
  107. }
  108. catch (const char* e)
  109. {
  110. cout << e;
  111. }
  112. }
  113.  
Success #stdin #stdout 0s 5432KB
stdin
{
    "username": "Nikkie",
    "password": "test",
    "role": "Developer",
    "email": "test@gmail.com"
}
stdout
Standard output is empty