[关闭]
@zzzc18 2019-12-18T11:51:51.000000Z 字数 3448 阅读 741

CodeBin

C++


  1. #define ZZZC18
  2. #include <cmath>
  3. #include <cstdio>
  4. #include <iostream>
  5. #include <map>
  6. #include <sstream>
  7. #include <stack>
  8. #include <string>
  9. #include <vector>
  10. using namespace std;
  11. enum TokenConst {
  12. END_DOCUMENT = 0, // JSON文档结束
  13. BEGIN_OBJECT, //开始一个JSON object {
  14. END_OBJECT, //结束一个JSON object }
  15. BEGIN_ARRAY, //开始一个JSON array [
  16. END_ARRAY, //结束一个JSON array ]
  17. COLON, //读取一个冒号
  18. COMMA, //读取一个逗号
  19. STRING, //一个String
  20. BOOLEAN, //一个true或false
  21. NUMBER, //一个number
  22. _NULL //一个null
  23. };
  24. class BUF {
  25. public:
  26. static const int MAXLEN = 30000;
  27. char str[MAXLEN];
  28. int len;
  29. int ptr;
  30. void init();
  31. char nextChar();
  32. char peekChar();
  33. string nextString(int);
  34. bool checkEOF();
  35. } file;
  36. class Token {
  37. public:
  38. vector<string> data;
  39. vector<string>::iterator I;
  40. void init(BUF*);
  41. TokenConst readToken();
  42. void displayToken(); // Debug purpose
  43. } token;
  44. double convertS2N(string& src) {
  45. double ret = 0, tmp;
  46. int sign = 1;
  47. int pos = 0;
  48. // sign
  49. if (src[0] == '-') {
  50. sign = -1;
  51. pos = 1;
  52. }
  53. // before dot
  54. tmp = 0;
  55. for (; pos < src.length(); pos++) {
  56. if (src[pos] < '0' || src[pos] > '9') break;
  57. tmp *= 10;
  58. tmp += src[pos] ^ '0';
  59. }
  60. ret += tmp;
  61. if (pos == src.length()) return ret * sign;
  62. // has dot
  63. tmp = 0;
  64. if (src[pos] == '.') {
  65. for (pos++; pos < src.length(); pos++) {
  66. if (src[pos] < '0' || src[pos] > '9') break;
  67. tmp *= 10;
  68. tmp += src[pos] ^ '0';
  69. }
  70. }
  71. while (tmp > 1) tmp /= 10;
  72. ret += tmp;
  73. if (pos == src.length()) return ret * sign;
  74. // has Exp
  75. tmp = 0;
  76. if (src[pos] == 'e' || src[pos] == 'E') {
  77. int e_sign = 1;
  78. if (src[++pos] == '-') {
  79. e_sign = -1;
  80. pos++;
  81. }
  82. for (; pos < src.length(); pos++) {
  83. if (src[pos] < '0' || src[pos] > '9') break;
  84. tmp *= 10;
  85. tmp += src[pos] ^ '0';
  86. }
  87. tmp *= e_sign;
  88. ret *= pow(10, tmp);
  89. }
  90. return ret * sign;
  91. }
  92. int main() {
  93. #ifdef ZZZC18
  94. freopen(".\\testdata\\C.json", "r", stdin);
  95. freopen("out.out", "w", stdout);
  96. #endif
  97. file.init();
  98. token.init(&file);
  99. token.displayToken();
  100. for (int i = 0; i < token.data.size(); i++) {
  101. cerr << token.readToken() << endl;
  102. token.I++;
  103. }
  104. return 0;
  105. }
  106. void BUF::init() {
  107. char ch;
  108. len = ptr = 0;
  109. while (scanf("%c", &ch) != EOF) {
  110. str[len++] = ch;
  111. }
  112. }
  113. char BUF::nextChar() { return str[ptr++]; }
  114. char BUF::peekChar() { return str[ptr]; }
  115. string BUF::nextString(int length) {
  116. static string ret;
  117. ret.clear();
  118. for (int i = 0; i < length; i++, ptr++) {
  119. ret.push_back(str[ptr]);
  120. }
  121. return ret;
  122. }
  123. bool BUF::checkEOF() { return ptr == len; }
  124. void Token::init(BUF* now) {
  125. static string tmp;
  126. while (!now->checkEOF()) {
  127. tmp.clear();
  128. char ch = now->nextChar();
  129. if (ch == '{') tmp.push_back('{');
  130. if (ch == '}') tmp.push_back('}');
  131. if (ch == '[') tmp.push_back('[');
  132. if (ch == ']') tmp.push_back(']');
  133. // bracket
  134. if (ch == ',') tmp.push_back(',');
  135. // comma
  136. if (ch == ':') tmp.push_back(':');
  137. // colone
  138. if (ch == '\"') { // string
  139. tmp.push_back(ch);
  140. while (true) {
  141. ch = now->peekChar();
  142. if (ch == '\\') {
  143. tmp.push_back(now->nextChar()); // character:'\'
  144. tmp.push_back(now->nextChar()); // character after '\'
  145. ch = now->peekChar();
  146. }
  147. if (ch == '\"') {
  148. tmp.push_back(now->nextChar());
  149. break;
  150. }
  151. tmp.push_back(now->nextChar());
  152. }
  153. }
  154. if ((ch >= '0' && ch <= '9') || ch == '-') { // number
  155. tmp.push_back(ch);
  156. while (true) {
  157. ch = now->peekChar();
  158. if ((ch >= '0' && ch <= '9') || ch == '.' || ch == 'e' ||
  159. ch == 'E' || ch == '+' || ch == '-')
  160. tmp.push_back(now->nextChar());
  161. else
  162. break;
  163. }
  164. }
  165. if (ch == 'n') { // null
  166. tmp.push_back(ch);
  167. // cerr << now->nextString(3) << endl;
  168. tmp += now->nextString(3);
  169. }
  170. if (ch == 't') { // true
  171. tmp.push_back(ch);
  172. tmp += now->nextString(3);
  173. }
  174. if (ch == 'f') { // false
  175. tmp.push_back(ch);
  176. tmp += now->nextString(4);
  177. }
  178. if (!tmp.empty()) data.push_back(tmp);
  179. }
  180. // initialize iterator
  181. I = data.begin();
  182. }
  183. void Token::displayToken() {
  184. for (int i = 0; i < data.size(); i++) {
  185. cout << data[i] << endl;
  186. }
  187. }
  188. TokenConst Token::readToken() {
  189. static string now = *I;
  190. if (now[0] == '{') return BEGIN_OBJECT;
  191. if (now[0] == '}') return END_OBJECT;
  192. if (now[0] == '[') return BEGIN_ARRAY;
  193. if (now[0] == ']') return END_ARRAY;
  194. if (now[0] == ':') return COLON;
  195. if (now[0] == ',') return COMMA;
  196. if (now[0] == '\"') return STRING;
  197. if (now[0] == 'n') return _NULL;
  198. if (now[0] == 't' || now[0] == 'f') return BOOLEAN;
  199. return NUMBER;
  200. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注