加载丑陋的输入

时间:2016-02-11 08:44:44

标签: c++

我需要知道如何在c ++中加载这样的输入

{ [1, 1], [2, 10] , [-10, 20] }

在C中我可以写出类似的东西:

if ( ( scanf(" %c",&bracket) ) != 1 || bracket != '{') {
    printf("Wrong input.\n");
    return 1;
} // 1st bracket


while(1) {

   if ( ( scanf(" %c%d%c%d%c",&bracket1,&arr[index][0],&dot,&arr[index][1],&bracket2) ) != 5  || bracket1 != '[' || bracket2 != ']' || dot != ',') {
       printf("Wrong input.\n");
       return 1;
   }

   if ( ( scanf(" %c",&tester) ) != 1 || ( tester != ',' && tester != '}' ) ) {
       printf("Wrong input.\n");
       return 1;
   }

   index++;

   if ( tester == '}' ) 
      break;

  } 

但我不知道如何在c ++中加载它并修复所有错误的输入。我尝试用cin加载它,但它没有用,无法用cin修复错误的输入。

1 个答案:

答案 0 :(得分:0)

你必须打破令牌(或词位)的输入。您的输入由7种类型的令牌组成:[ ] { } , number end_of_file

可能的解决方案:

// tokens definition
enum token
{
  open_obj,
  close_obj,
  open_pair,
  close_pair,
  comma,
  number,
  end
};

// scanner
class scanner_type
{
  std::istream& mis;

public:

  token mt;
  int mn;

  scanner_type( std::istream& ais ) : mis( ais ) {}

  token get()
  {
    std::ws( mis ); // eat white

    char c;
    if ( ! mis.get( c ) )
      return mt = token::end;

    switch ( c )
    {
    case '[': return mt = token::open_pair;
    case ']': return mt = token::close_pair;
    case '{': return mt = token::open_obj;
    case '}': return mt = token::close_obj;
    case ',': return mt = token::comma;
    default:
      if ( std::isdigit( c ) || c == '-' || c == '+' )
      {
        mis.unget();
        mis >> mn;
        return mt = token::number;
      }
      else
      {
        throw "unexpected character";
      }
    };
  }
};

int main()
{
  std::stringstream ss( "{ [1, 1], [2, 10] , [-10, 20] }" );
  scanner_type sc( ss );

  assert( sc.get() == token::open_obj );
  assert( sc.get() == token::open_pair );
  assert( sc.get() == token::number );
  assert( sc.mn == 1 );
  // ...

  return 0;
}

阅读有关扫描仪的here