Manipuladores de fluxo personalizados para modificar a saída subsequente em C
Em C, os manipuladores de fluxo são ferramentas poderosas para personalizar e aprimorar operações de entrada e saída. Um manipulador comum é std::hex, que modifica o formato da saída numérica subsequente para hexadecimal.
No entanto, e se você precisar de um manipulador que não apenas adicione elementos adicionais ao fluxo, mas também modifique os valores dos itens que vem depois? Este artigo explora como criar tal manipulador e demonstra seu caso de uso com um exemplo simples.
Manipuladores personalizados com armazenamento de estado
Para modificar itens subsequentes no fluxo, você precisa armazenar informações de estado associadas a cada fluxo. Isso pode ser conseguido usando a função ios_base::iword e um índice gerado por xalloc.
inline int geti() { static int i = ios_base::xalloc(); return i; }
Com esse mecanismo implementado, você pode definir dois manipuladores: add_one e add_none. add_one define o estado armazenado como 1, enquanto add_none define como 0.
ostream& add_one(ostream& os) { os.iword(geti()) = 1; return os; } ostream& add_none(ostream& os) { os.iword(geti()) = 0; return os; }
Personalizando a saída numérica
A saída numérica em C é tratada por facetas. Para modificar o comportamento da saída numérica, você pode definir uma faceta personalizada. Aqui, criamos uma faceta personalizada chamada my_num_put que incrementa cada valor numérico pelo valor do estado armazenado.
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())); } };
Testando o manipulador
Para testar o manipulador personalizado, você pode imbuir o fluxo de saída com a nova faceta e usar os manipuladores para modificar a saída numérica.
int main() { // outputs: 11121011 cout.imbue(locale(locale(), new my_num_put)); cout << add_one << 10 << 11 << add_none << 10 << 11; }
Neste exemplo, o fluxo de saída imprimirá os números 10, 11, 10 e 11 com o valor 1 adicionado a cada um dos dois primeiros números, resultando em 11, 12, 10 e 11.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3