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:
#incluirusando 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.
I / O Manipulador | Funçã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. |
ws | Este objeto come espaço em branco a partir de um fluxo de entrada. |
extremidades | Insere um caractere nulo (' 0') Em um outputstream. Útil para null-encerra uma string ao usar ostrstream. |
rubor | Libera todos os caracteres do buffer para o fluxo de saída. |
endl | Insere 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.