fork(1) download
  1. #include <string>
  2. #include <iostream>
  3. #include <vector>
  4. #include <array>
  5. #include <complex>
  6.  
  7.  
  8. template<class e, class t, int N>
  9. std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&sliteral)[N]) {
  10. std::array<e, N-1> buffer; //get buffer
  11. in >> buffer[0]; //skips whitespace
  12. if (N>2)
  13. in.read(&buffer[1], N-2); //read the rest
  14. if (strncmp(&buffer[0], sliteral, N-1)) //if it failed
  15. in.setstate(in.rdstate() | std::ios::badbit); //set the state
  16. return in;
  17. }
  18. template<class e, class t>
  19. std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& cliteral) {
  20. e buffer; //get buffer
  21. in >> buffer; //read data
  22. if (buffer != cliteral) //if it failed
  23. in.setstate(in.rdstate() | std::ios::badbit); //set the state
  24. return in;
  25. }
  26. template<class e, class t, int N>
  27. std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
  28. return std::operator>>(in, carray);
  29. }
  30. template<class e, class t, class a>
  31. std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, a& obj) {
  32. return in >> obj; //read data
  33. }
  34.  
  35. template<class T>
  36. std::istream& custom_complex(std::istream& file, std::complex<T>& obj) {
  37. if (!file)
  38. return file;
  39. std::string fullline;
  40. std::getline(file, fullline);
  41. T r, i;
  42. std::stringstream ss(std::move(fullline));
  43. if (ss >> '(' >> r >> ',' >> 'i' >> ')') {
  44. obj = std::complex<T>(r, i);
  45. return file;
  46. }
  47. ss.clear();
  48. ss.seekg(0);
  49. if (ss >> '(' >> r >> 'i' >> ')') {
  50. obj = std::complex<T>(r, i);
  51. return file;
  52. }
  53. ss.clear();
  54. ss.seekg(0);
  55. if (ss >> r >> ',' >> i) {
  56. obj = std::complex<T>(r, i);
  57. return file;
  58. }
  59. ss.clear();
  60. ss.seekg(0);
  61. if (ss >> r >> i) {
  62. obj = std::complex<T>(r, i);
  63. return file;
  64. }
  65. file.setstate(file.rdstate() | std::ios::badbit);
  66. return file;
  67. }
  68.  
  69. struct first {
  70. std::string name;
  71. double something;
  72. };
  73. struct second {
  74. int myint;
  75. std::complex<double> mycomplex;
  76. };
  77. struct mega {
  78. std::vector<first> list1;
  79. std::vector<second> list2;
  80. };
  81.  
  82. std::istream& operator>>(std::istream& file, first& obj) {
  83. std::string symbol;
  84. char equals;
  85. while(file >> symbol) {
  86. if (symbol[0] == '#') {
  87. std::getline(file, symbol);
  88. } else if (symbol == "<FIRST_END>") {
  89. break;
  90. } else if (symbol == "NAME") {
  91. if (! (file>>'='>>obj.name) )
  92. std::cerr << symbol << " incorrectly formatted";
  93. } else if (symbol == "SOMETHING") {
  94. if (! (file>>'='>>obj.something) )
  95. std::cerr << symbol << " incorrectly formatted";
  96. } else { //not a member: failure
  97. std::cerr << symbol << " is not a member of first";
  98. file.setstate(file.rdstate() | std::ios::badbit);
  99. break;
  100. }
  101. }
  102. return file;
  103. }
  104. std::istream& operator>>(std::istream& file, second& obj) {
  105. std::string symbol;
  106. char equals;
  107. while(file >> symbol) {
  108. if (symbol[0] == '#') {
  109. std::getline(file, symbol);
  110. } else if (symbol == "<SECOND_END>") {
  111. break;
  112. } else if (symbol == "INT") {
  113. if (! (file>>'='>>obj.myint) )
  114. std::cerr << symbol << " incorrectly formatted";
  115. } else if (symbol == "COMPLEX") {
  116. if (! (file>>'=' && custom_complex(file,obj.mycomplex)) )
  117. std::cerr << symbol << " incorrectly formatted";
  118. } else { //not a member: failure
  119. std::cerr << symbol << " is not a member of second";
  120. file.setstate(file.rdstate() | std::ios::badbit);
  121. break;
  122. }
  123. }
  124. return file;
  125. }
  126.  
  127. std::istream& operator>>(std::istream& file, mega& obj) {
  128. std::string symbol;
  129. while(file >> symbol) {
  130. if (symbol[0] == '#') {
  131. std::getline(file, symbol);
  132. } else if (symbol == "<FIRST_BEGIN>") {
  133. first t;
  134. if (file >> t)
  135. obj.list1.push_back(t);
  136. } else if (symbol == "<SECOND_BEGIN>") {
  137. second t;
  138. if (file >> t)
  139. obj.list2.push_back(t);
  140. } else {
  141. std::cerr << symbol << " is not a member of mega";
  142. file.setstate(file.rdstate() | std::ios::badbit);
  143. }
  144. }
  145. return file;
  146. }
  147.  
  148. int main() {
  149. mega obj;
  150. std::cin >> obj;
  151. std::cout << obj.list2.size(); //1 if success
  152. }
Success #stdin #stdout 0s 3032KB
stdin
<FIRST_BEGIN>
  NAME = myname
  SOMETHING = 5.0
<FIRST_END>

<SECOND_BEGIN>
  INT = 5
  COMPLEX = 5.0 1.0
<SECOND_END>
stdout
1