Пример перегрузки оператора извлечения C++ ›› для разбора данных

Я ищу хороший пример того, как перегрузить оператор ввода потока (operator>>) для анализа некоторых данных с помощью простого форматирования текста. Я прочитал это руководство, но хотел бы сделать что-то более продвинутое. В моем случае у меня есть фиксированные строки, которые я хотел бы проверить (и игнорировать). Предположим, что формат 2D-точки из ссылки больше похож на

Point{0.3 =>
      0.4 }

где предполагаемый эффект состоит в том, чтобы разобрать числа 0,3 и 0,4. (Да, это ужасно глупый синтаксис, но он включает в себя несколько нужных мне идей). В основном я просто хочу посмотреть, как правильно проверять наличие фиксированных строк, игнорировать пробелы и т. д.

Обновление: К сожалению, комментарий, который я оставил ниже, не имеет форматирования (я впервые пользуюсь этим сайтом). Я обнаружил, что пробелы можно пропустить с помощью чего-то вроде

std::cin >> std::ws;

И для того, чтобы съесть струны, у меня есть

static bool match_string(std::istream &is, const char *str){
    size_t nstr = strlen(str);
    while(nstr){
        if(is.peek() == *str){
            is.ignore(1);
            ++str;
            --nstr;
        }else{
            is.setstate(is.rdstate() | std::ios_base::failbit);
            return false;
        }
    }
    return true;
}

Теперь было бы неплохо иметь возможность получить позицию (номер строки) ошибки синтаксического анализа.

Обновление 2: нумерация строк и синтаксический анализ комментариев теперь работают, используя всего 1 символ упреждения. Окончательный результат можно увидеть здесь в AArray.cpp, в функции parse() . Проект представляет собой (де)сериализуемый класс C++ PHP-подобного массива.


person Victor Liu    schedule 10.09.2009    source источник
comment
Это не оператор извлечения или ввода потока, это оператор сдвига битов. Версии потокового ввода-вывода сами по себе являются перегруженными версиями оригинального оператора C, который относительно мало используется на практике.   -  person Chris Lutz    schedule 10.09.2009
comment
Крис: Хотя я не согласен с вами, похоже, принято называть операторы '››' и '‹‹' независимо друг от друга операторами потокового ввода/вывода. См. определения ‹‹ и ›› в глоссарии Страуструпа: research.att.com/~bs /glossary.html   -  person GRB    schedule 10.09.2009
comment
@GRB: перегрузка оператора - нет. Побитовый оператор сдвига вправо был использован в C++ stl. Рассмотрим оператор ^. Вы можете решить использовать перегрузку оператора, чтобы превратить его в оператор возведения в степень. Однако он просто имеет неправильный приоритет и ассоциативность. Учитывая, что новые новые операторы не могут быть добавлены, а семантика существующих операторов не может быть изменена, И механика, неявная в терминологии: перегрузка, оператор ›› является побитовым оператором сдвига вправо, а все остальное понимается как перегруженная форма.   -  person Chris Becke    schedule 10.09.2009
comment
Крис Б: Опять же, я не согласен. Тем не менее, перегрузка '‹‹' и '››' для потоков настолько повсеместна, что теперь приемлемо обращаться к ним отдельно как к потоковым 'операторам'. Мое единственное замечание состоит в том, что мы не должны ругать Виктора за то, что он использовал (очевидно) общепринятую терминологию; см. мою ссылку Страуструпа.   -  person GRB    schedule 10.09.2009
comment
Я собрал решение, которое пропускает пробелы с чем-то вроде «cin ›› ws» и сопоставляет строки с кодом вроде static bool match_string(std::istream &is, const char *str){ size_t nstr = strlen(str); while(nstr){ if(is.peek() == *str){ is.ignore(1); ++стр; --нстр; }else{ is.setstate(is.rdstate() | std::ios_base::failbit); вернуть ложь; } } вернуть истину; }   -  person Victor Liu    schedule 10.09.2009
comment
Почему бы вам не опубликовать свое решение в качестве ответа. Вы можете получить одобрение и даже получить значок самоучителя!   -  person Ropez    schedule 11.09.2009


Ответы (1)


Ваш оператор>>(istream &, object &) должен получить данные из входного потока, используя его форматированные и/или неформатированные функции извлечения, и поместить их в ваш объект.

Если вы хотите быть более безопасным (после моды), создайте и протестируйте объект istream::sentry перед тем, как начать. Если вы столкнулись с синтаксической ошибкой, вы можете вызвать setstate( ios_base::failbit ), чтобы предотвратить любую другую обработку, пока не вызовете my_stream.clear().

См. <istream> (и istream.tcc, если вы используете SGI STL) для примеров.

person Potatoswatter    schedule 10.09.2009