LINUX.ORG.RU

Ввести «jV\\x11\\x32» и распарсить?

rival ★★
()
#include <algorithm>
#include <iterator>
#include <iostream>
#include <string>

using namespace std;

struct unexpected_character 
{
  char c;
  explicit unexpected_character(char c) : c(c) { }
};

struct ascii_to_char_iterator : iterator<output_iterator_tag, char>
{
  enum class state { NORMAL, ESCAPE, ESCAPE_HEX_1, ESCAPE_HEX_2,  ESCAPE_OCT_2, ESCAPE_OCT_3 };

  string& s;
  state st;
  char code;
  explicit ascii_to_char_iterator(string& s) : s(s), st(state::NORMAL) { }

  ascii_to_char_iterator& operator* () { return *this; }
  const ascii_to_char_iterator& operator* () const { return *this; }

  ascii_to_char_iterator& operator++ () { return *this; }
  ascii_to_char_iterator& operator++ (int) { return *this; }

  ascii_to_char_iterator& operator= (char c)
  {
    switch (st)
      {
      case state::NORMAL:
        if (c == '\\')
          st = state::ESCAPE;
        else
          s += c;
        break;
      case state::ESCAPE:
        switch (c)
          {
          case 'a': s += '\a'; break;
          case 'b': s += '\b'; break;
          case 'f': s += '\f'; break;
          case 'n': s += '\n'; break;
          case 'r': s += '\r'; break;
          case 't': s += '\t'; break;
          case 'v': s += '\v'; break;
          case '\\': s += '\\'; break;
          case '?': s += '?'; break;
          case '\'': s += '\''; break;
          case '"': s += '"'; break;
          case 'x': st = state::ESCAPE_HEX_1; break;
          case '0'...'7': 
            code = c - '0';
            st = state::ESCAPE_OCT_2;
            break;
          default:
            throw unexpected_character(c);
          }
        if (st == state::ESCAPE) st = state::NORMAL;
        break;
      case state::ESCAPE_HEX_1:
        switch (c)
          {
          case '0'...'9': 
            code = c - '0';
            break;
          case 'a'...'f':
            code = c - 'a';
            break;
          case 'A'...'F':
            code = c - 'A';
            break;
          default:
            throw unexpected_character(c);
          }
        st = state::ESCAPE_HEX_2;
        break;
      case state::ESCAPE_HEX_2:
        switch (c)
          {
          case '0'...'9': 
            code = (code << 4) bitor (c - '0');
            break;
          case 'a'...'f':
            code = (code << 4) bitor (10 + c - 'a');
            break;
          case 'A'...'F':
            code = (code << 4) bitor (10 + c - 'A');
            break;
          default:
            throw unexpected_character(c);
          }

        s += code;
        st = state::NORMAL;
        break;
      case state::ESCAPE_OCT_2:
        switch (c)
          {
          case '0'...'7': 
            code = (code << 3) bitor (c - '0');
            break;
          default:
            throw unexpected_character(c);
          }
        st = state::ESCAPE_OCT_3;
        break;
      case state::ESCAPE_OCT_3:
        switch (c)
          {
          case '0'...'7': 
            code = (code << 3) bitor (c - '0');
            break;
          default:
            throw unexpected_character(c);
          }
        s += code;
        st = state::NORMAL;
        break;
      }
  }
};

int main()
{
  string s1;
  getline(cin, s1);
  string s2;
  std::copy(s1.begin(), s1.end(), ascii_to_char_iterator(s2));
  cout << s2 << std::endl;
}
Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

У вас пипец, а у Керниган и Пайка — задачка на две строки.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.