Пользовательские манипуляторы потоков для изменения последующего вывода в 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