Вырваться из перегруженного оператора извлечения? (C ++) - PullRequest
4 голосов
/ 10 февраля 2010

Я пытаюсь использовать перегруженное ">>" для сканирования ввода из файла.

Проблема в том, что я понятия не имею, что делать с концом файла. В этом случае мой файл состоит из числа, за которым следуют несколько символов

Ex:

9rl

1011 * 6 и далее *

istream &operator>>(istream &is, Move &move)
{
  char c;
  int i = 0;

  c = is.get();

  if (!isalnum(c))
      return;

  move.setNum(c); // I convert the char to an int, but I'l edit it out

  while ( (c = is.get()) != '\n')
  {
    move.setDirection(i, c); //sets character c into in array at index i
    i++;

  } // while chars are not newline

  return is;
} // operator >>

Тест на символ, являющийся буквенно-цифровым символом, работал, когда у меня было это как обычная функция, но не работает здесь, поскольку он ожидает, что входной поток будет возвращен. Я также пытался вернуть NULL. Предложения?

РЕДАКТИРОВАТЬ: это вызывается в цикле while, поэтому я пытаюсь найти какой-то способ, чтобы у этого триггера был какой-то флаг, чтобы я мог выйти из цикла. В моей предыдущей функции это возвращало логическое значение, возвращая true в случае успеха или false, если символ не был буквенно-цифровым

Ответы [ 2 ]

2 голосов
/ 10 февраля 2010

Вы можете установить флаги потока в такое состояние, как ios :: bad или ios :: fail , используя ios :: setstate . Это позволит вызывающей стороне протестировать поток или, если для потока включены исключения, возникнет исключение.

Вы также не можете проверить состояние вашего потока. В C ++ FAQ Lite есть отличный раздел , объясняющий это. Чтобы прояснить это, я добавил фрагмент кода ниже.

c = is.get();
// the stream has not been tested to see if it read into c correctly
if (!isalnum(c))
    return;
2 голосов
/ 10 февраля 2010

Возврат is. Вызывающие абоненты должны проверить поток на наличие ошибок.

Обязательно установите соответствующие биты ошибок:

std::istream &operator>>(std::istream &is, Move &move)
{
  char c;
  int i = 0;

  c = is.get();
  if (is.eof())
    return is;
  else if (c < '0' || c > '9') {
    is.setstate(std::ios::badbit);
    return is;
  }
  else
    move.setNum(c-'0');

  while ( (c = is.get()) != '\n' && is)
    move.setDirection(i++, c);

  if (c != '\n')
    is.setstate(std::ios::badbit);
  return is;
}

Используйте его следующим образом:

int main(int argc, char **argv)
{
  std::stringstream s;

  s << "9rl\n"
    << "8d\n"
    << "6ff\n";
  s.seekg(0);

  Move m;
  while (s >> m)
    std::cout << m;

  if (s.bad())
    std::cerr << argv[0] << ": extraction failed\n";

  return 0;
}

Обратите внимание, что код использует экземпляр m только после успешного извлечения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...