Переопределяющий оператор >> для класса Strings - PullRequest
0 голосов
/ 09 ноября 2010

У меня просто быстрый вопрос. Мне нужно переопределить оператор >> для пользовательского класса String, и я не могу понять, как это сделать.

Я знаю, что этот код работает, потому что это был мой оригинальный метод решения проблемы:

istream& operator>>(istream &is, String &s) {
  char data[ String::BUFF_INC ];  //BUFF_INC is predefined
  is >> data;
  delete &s;
  s = data;
  return s;
}

Однако, согласно спецификации (это домашнее задание), мне нужно читать по 1 символам за раз, чтобы вручную проверять наличие пробелов и убедиться, что строка не слишком велика для данных []. Поэтому я изменил свой код на следующее:

istream& operator>>(istream &is, String &s) {
  char data[ String::BUFF_INC ];
  int idx = 0;
  data[ 0 ] = is.get();
  while( (data[ idx ] != *String::WHITESPACE) && !is.ios::fail() ) {
    ++idx;
    is.get();
    data[ idx ] = s[ idx ];
  }
  return is;
}

Когда этот новый код выполняется, он просто застревает в цикле пользовательского ввода. Итак, как мне использовать is.get (), чтобы читать данные за символом, но не ждать ввода данных пользователем? Или, может быть, я должен использовать что-то другое, чем .get ()?

Ответы [ 2 ]

1 голос
/ 09 ноября 2010

Вы, похоже, ничего не делаете с символом, полученным из потока

istream& operator>>(istream &is, String &s) {
  char data[ String::BUFF_INC ];
  int idx = 0;
  data[ 0 ] = is.get();
  while( (data[ idx ] != *String::WHITESPACE) && !is.ios::fail() ) {
    ++idx;
    is.get();              // you don't do anything with this
    data[ idx ] = s[ idx ]; // you're copying the string into the buffer
  }
  return is;
}

Таким образом, он проверяет, содержит ли строка s пробел, а не считываете ли вы пробел из потока.

1 голос
/ 09 ноября 2010

Попробуйте:

istream& operator>>(istream &is, String &s)
{
    std::string  buffer;
    is >> buffer;           // This reads 1 white space separated word.

    s.data = buffer.c_str();
    return is;
}

Комментируя ваш оригинальный код:

istream& operator>>(istream &is, String &s)
{
  char data[ String::BUFF_INC ];
  is >> data;   // Will work. But prone to buffer overflow.


  delete s;    // This line is definately wrong.
               // s is not a pointer so I don;t know what deleting it would do.

  s = data;    // Assume assignment operator is defined.
               // for your class that accepts a C-String
  return s;
}

Использование второй версии в качестве базы:

istream& operator>>(istream &is, String &s)
{
  std::vector<char> data;

  char first;
  // Must ignore all the white space before the word
  for(first = is.get(); String::isWhiteSpace(first) && is; first = is.get())
  {}

  // If we fond a non space first character
  if (is && !String::isWhiteSpace(first))
  {
      data.push_back(first);
  }


  // Now get values while white space is false
  char next;
  while( !String::isWhiteSpace(next = is.get()) && is)
  {
      // Note we test the condition of the stream in the loop
      // This is because is.get() may fail (with eof() or bad()
      // So we test it after each get.
      //
      // Normally you would use >> operator but that ignores spaces.
      data.push_back(next);
  }
  // Now assign it to your String object
  data.push_back('\0');
  s.data = data;
  return is;
}
...