Fluxo de formatação com Manipuladores de I / O

Uma das dificuldades com C ++ em movendo-se para transmitir objetos para a saída é aprender a formatar a saída. Na verdade, existem duas maneiras de formatar-stream E / S.

A primeira técnica que os programadores normalmente aprender é através de chamadas de método direto. Por exemplo, a chamada seguinte define o fluxo de saída no modo hexadecimal para que apareça no ecrã inteiros como valores hexadecimais em vez de valores decimais como:

ios :: fmtflags prev = cout.setf (ios :: hex, ios :: basefield) -

aqui o setf () método define os sinalizadores de formato pelo primeiro mascarando fora os bits no segundo argumento e, em seguida, definindo os bits indicados pelo primeiro argumento. A função retorna o valor antigo para que a função de chamada pode restaurar as bandeiras de formato antes de retornar.

Na prática, esta função parece como se segue:

#incluir usando namespace std - // displayHex - exibir um número em hexadecimal formatvoid displayHex (ostream para fora, int n) {ios :: fmtflags prev = out.setf (ios :: hex, ios :: basefield) Check-out lt; lt; n-out.setf (ant) -} int main () {int n = 0x1234-cout lt; lt; "N =" lt; lt; n lt; lt; endl-cout lt; lt; "N em hexadecimal é" -displayHex (cout, n) -cout lt; lt; endl-retorno 0-}

O programa começa definindo a variável n a um valor hexadecimal. Em seguida, apresenta o valor para cout. Em seguida, chama o displayHex () função para exibir o valor em formato hexadecimal. A saída do programa aparece como segue:

n = 4660n em hexadecimal é 1234

O valor em formato decimal não é reconhecível, mas a exibição hexadecimal é claramente o valor usado para inicializar n.

No entanto, C ++ fornece uma segunda maneira de controlar I / O formato: Os manipuladores de I / O.

O que é um / O manipulador I?

A I / O manipulador é um objeto que o programador pode inserir no fluxo de saída para invocar as funções de controle de formato. O seguinte trecho de código demonstra o usuário de manipuladores de E / S. Ele executa a mesma função que o fragmento prévio, excepto esta versão usa um manipulador de I / O para chamar o setf () função:

#incluir #incluir usando namespace std-int main () {int n = 0x1234-cout lt; lt; "N =" lt; lt; n lt; lt; endllt; lt; "N em hexadecimal é" lt; lt; setbase (16) lt; lt; n lt; lt; endl-retorno 0-}

Aqui a Principal() primeiro saídas n como um valor decimal. Em seguida, ele usa o setbase (16) manipulador para alterar a base de exibição de decimal (base 10) para hexadecimal (base 16) antes de exibir o valor novamente. A saída a partir desta versão é indistinguível da versão anterior:

n = 4660n em hexadecimal é 1234

o setbase (16) objecto aparece como uma chamada para uma função no meio do fluxo de saída. O fato de que um objeto está sendo criado é invisível para o usuário.

Para hexadecimal, octal e decimal, C ++ fornece os atalhos feitiço, outubro e dezembro o que significa que o código poderia assumir a seguinte forma ainda mais curto:

cout lt; lt; "N =" lt; lt; n lt; lt; endllt; lt; "N em hexadecimal é" lt; lt; feitiço lt; lt; n lt; lt; endl-

O que I / manipuladores O que C ++ oferece?

Ter um olhar para esta tabela, que contém uma lista de E / S manipuladores disponíveis para C ++ 2011.

Manipuladores O comum I /
I / O ManipuladorFunção
boolalpha
noboolalpha
Alterna entre textual e mostrador numérico de um booleano. Quandoboolalpha é definido, o verdadeiro eo falso appearonscreen como 'verdade' e 'falso'. Quando não está definido, eles aparecem como '1"E" 0 ".
showbase
noshowbase
Quando showbase é definido, octal valuesare precedido por um 0 e hexadecimalvalues ​​são precedidos por '0x' ou '0X'.
showpoint
noshowpoint
Um ponto decimal é sempre exibido quando showpoint está definido.
showpos
noshowpos
exibe uma '+' assinar em valores ofpositive da frente quando showpos set.Displays é nada quando noshowpos isset.
skipws
noskipws
Ignora levando espaço em branco na entrada.
maiúscula
nouppercase
E se maiúscula é definido, então useuppercase para formatos de saída, por exemplo, '0X'Para a saída hexadecimal. Se nouppercase está definido, use letras minúsculas, por exemplo,'0x'Para a saída hexadecimal.
unitbuf
nounitbuf
Se for definido, então a saída não é tamponado mas liberado após eachinsert. Se não for definido, a saída é tamponada.
fixo
científico
Definir a saída de valores de ponto flutuante para qualquer notação orscientific fixa.
wsEste objeto come espaço em branco a partir de um fluxo de entrada.
extremidadesInsere um caractere nulo (' 0') Em um outputstream. Útil para null-encerra uma string ao usar ostrstream.
ruborLibera todos os caracteres do buffer para o fluxo de saída.
endlInsere um caractere de nova linha.
setiosflags(N)
resetiosflags(N)
Definir ou limpar o ios bandeiras enmasse.
setbase (n)Define a base para entrada e saída inteiro para 8, 10, 16 ou texto 0.See para a explicação de 0.
dezembro

outubro
feitiço
Definir a base para decimal, octal ou hexadecimal.
abreviada para setbase (10), setbase (8), e setbase (16), respectivamente.
setfill (c)Define o caractere usado para preencher o espaço quando o número ofcharacters para exibir é menor do que a largura do campo. O defaultcharacter é um espaço.
setprecision (n)Define o número de dígitos para a saída ao exibir número de ponto-afloating.
setw (n)Define a largura mínima do campo de saída seguinte. O campo IsExpanded com setfill () caracteres asnecessary.
setfill (c)Define o caractere usado para preencher o espaço quando o número ofcharacters para exibir é menor do que a largura do campo. O defaultcharacter é um espaço.


interno
esquerda
certo
Definir a colocação de caracteres de preenchimento. Se o enchimento characterwere '*' (por exemplo), em seguida:
interno -"$ 123.00 **"
esquerda - "** $ 123,00"
certo - "$ 123,00 **"
get_money ()
put_money ()
Ler ou exibir um valor monetário, usando as regras locais como locale setby. (Isto não é implementada na versão atual ofgcc.)
consiga tempo()
put_time ()
Leia ou exibir uma hora ou data, usando as regras locais como conjunto bylocale. (Isto não é implementada na versão atual ofgcc.)

A maioria dos manipuladores são simples. Alguns exigem uma explicação, no entanto. Por exemplo, em relação à setbase () manipulador, nem todos os valores de base são suportados. Na verdade, C ++ suporta apenas decimal, octal e hexadecimal I / O - que é ok, como isso é muito bonito tudo que é necessário. Você pode, no entanto, definir a base para 0 - na verdade, 0 é o valor padrão.

Definir a base para 0 é o mesmo que defini-lo para decimal para a saída. Para a entrada, no entanto, a configuração da base para 0 significa "extrair a base do próprio número". As regras para o fazer são os seguintes:

  • # 42 Se um número começa com 0x ou 0X, presume-se que seja hexadecimal.

  • # 42 Se um número começa com apenas 0, então supõe-se para ser octal.

  • # 42-Caso contrário, o número é assumido como sendo decimal.

O seguinte programa simples demonstra as seguintes regras:

#incluir #incluir usando namespace std-int main () {int n1, n2, n3-cin >> setbase (0) >> n1 >> n2 >> n3-cout lt; lt; showbase lt; lt; setbase (16) lt; lt; "= n1" lt; lt; n1 lt; lt; ", = n2" lt; lt; n2lt; lt; ", N3 =" lt; lt; n3 lt; lt; endl-retorno 0-}

A primeira linha estabelece a base para o cin opor-se a 0 e, em seguida, extrai três inteiros. A segunda linha mostra estas três inteiros em formato hexadecimal. o showbase manipulador faz com que o líder '0x' a ser exibido para valores hexadecimais. O seguinte mostra um exemplo de execução deste programa, onde os três números em negrito são os valores que a entrada do teclado:

10 010 0x10n1 = 0xa, n2 = 0x8, n3 = 0x10

Você pode ver que o primeiro número foi interpretado como 10 em base 10, que é 0xA em hexadecimal. O segundo número foi interpretado como 10 na base 8, o qual é 8 em hexadecimal. O terceiro e último número foi interpretado como 10 em hexadecimal.

Outro manipulador que merece destaque especial é o setw (), abreviação de "width set". Isso define a largura mínima de exibição do próximo campo exibido. O seguinte programa simples mostra como setw ()interage com estofamento e o caractere de preenchimento:

#incluir #incluir usando namespace std-int main () {int width-int valor cout lt; lt; "Insira a largura:" - cin >> largura cout lt; lt; setfill ( '*') - para (-) {cout lt; lt; "Insira um valor:" - cin >> value-if (valor == 0) {} break-cout lt; lt; "Esquerda, Direita e interna: n" lt; lt; esquerda lt; lt; setw (largura) lt; lt; valor lt; lt; "," Lt; lt; rightlt; lt; setw (largura) lt; lt; valor lt; lt; "," Lt; lt; interno lt; lt; setw (largura) lt; lt; valor lt; lt; endl-} return 0-}

Este programa define o caractere de preenchimento para '*' (O padrão é o espaço). Em seguida, lê a largura a ser utilizado para todos os números do teclado antes de entrar um circuito que lê e exibe valores. Dentro deste ciclo, o primeiro programa exibe o número de esquerda; preenchimento lado, em seguida, com direito; preenchimento lado, e, finalmente, com preenchimento interno.

O que se segue é um exemplo de execução do programa com a entrada em negrito:

Insira a largura:5Insira um valor:100000Esquerda, Direita e interno: 100000, 100000, 100000Enter um valor:100Esquerda, Direita e interna: 100 **, ** 100, ** 100Enter um valor:-100Esquerda, Direita e interno: -100 *, * -100, - * 100Enter um valor:0

Aqui 5 é inserido como a largura do campo. No entanto, o primeiro valor inserido, 100.000, requer mais do que 5 colunas para exibir de modo nenhum dos campos de exibição teve qualquer efeito. A largura aparelho só define a largura mínima para exibir.

O próximo valor inserido, 100, requer apenas três colunas para exibir, para que o programa exibido o valor em primeiro lugar com dois * caracteres à direita, em seguida, à esquerda, e novamente à esquerda.

O próximo valor inserido, -100, demonstra a diferença entre certo e preenchimento de preenchimento interno. preenchimento certo colocar o caractere de preenchimento à esquerda do valor, incluindo o sinal de menos. preenchimento Interno colocar o caractere de preenchimento entre o valor eo sinal de menos. Isso também funciona para um sinal de mais, quando mais é forçado com o showpos manipulador e entre o número e o sinal de moeda (quando a moeda é suportada pelo compilador).

Os manipuladores não adicionar qualquer capacidade que já não está presente. Afinal, cada um desses manipuladores acaba chamando um método público sobre o objeto de fluxo. No entanto, eles não fornecem um meio conveniente de formatação de I / O.

menu