«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Как создать собственные манипуляторы потоков, влияющие на последующие выходные данные в C++?

Как создать собственные манипуляторы потоков, влияющие на последующие выходные данные в C++?

Опубликовано 14 ноября 2024 г.
Просматривать:124

How to Create Custom Stream Manipulators that Affect Subsequent Outputs in C  ?

Пользовательские манипуляторы потоков для изменения последующего вывода в C

В C манипуляторы потоков представляют собой мощные инструменты для настройки и улучшения операций ввода и вывода. Одним из распространенных манипуляторов является std::hex, который изменяет формат последующего числового вывода на шестнадцатеричный.

Однако что, если вам нужен манипулятор, который не только добавляет дополнительные элементы в поток, но и изменяет значения элементов что последует за этим? В этой статье рассматривается, как создать такой манипулятор, и демонстрируется вариант его использования на простом примере.

Пользовательские манипуляторы с хранилищем состояний

Чтобы изменить последующие элементы в потоке, вам необходимо хранить информацию о состоянии, связанную с каждым потоком. Этого можно добиться с помощью функции ios_base::iword и индекса, сгенерированного xalloc.

inline int geti() {
    static int i = ios_base::xalloc();
    return i;
}

При наличии этого механизма вы можете определить два манипулятора: add_one и add_none. add_one устанавливает сохраненное состояние на 1, а add_none устанавливает его на 0.

ostream& add_one(ostream& os) { os.iword(geti()) = 1; return os; }
ostream& add_none(ostream& os) { os.iword(geti()) = 0; return os; }

Настройка числового вывода

Числовой вывод в C обрабатывается фасетами. Чтобы изменить поведение числового вывода, вы можете определить пользовательский фасет. Здесь мы создаем пользовательский фасет под названием my_num_put, который увеличивает каждое числовое значение на сохраненное значение состояния.

struct my_num_put : num_put<char> {
    iter_type do_put(iter_type s, ios_base& f, char_type fill, long v) const {
        return num_put<char>::do_put(s, f, fill, v   f.iword(geti()));
    }

    iter_type do_put(iter_type s, ios_base& f, char_type fill, unsigned long v) const {
        return num_put<char>::do_put(s, f, fill, v   f.iword(geti()));
    }
};

Тестирование манипулятора

Чтобы протестировать собственный манипулятор, вы можете наполнить поток вывода новым аспектом и использовать манипуляторы для изменения числового вывода.

int main() {
    // outputs: 11121011
    cout.imbue(locale(locale(), new my_num_put));
    cout << add_one << 10 << 11 << add_none << 10 << 11;
}

В этом примере выходной поток выведет числа 10, 11, 10 и 11 со значением 1, добавленным к каждому из первых двух чисел, в результате чего получатся 11, 12, 10 и 11.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3