Пример перегрузки оператора извлечения C ++ >> для разбора данных - PullRequest
5 голосов
/ 10 сентября 2009

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

1 Ответ

1 голос
/ 10 сентября 2009

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

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

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

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