"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como criar manipuladores de fluxo personalizados que afetam as saídas subsequentes em C++?

Como criar manipuladores de fluxo personalizados que afetam as saídas subsequentes em C++?

Publicado em 2024-11-14
Navegar:272

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

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.

Tutorial mais recente Mais>

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