Como formatar strings usando printf () para obter o mesmo comprimento na saída?

91

Tenho duas funções, uma que produz mensagens semelhantes Starting initialization...e outra que verifica códigos de retorno e saídas "Ok", "Warning"ou "Error". No entanto, a saída produzida é de comprimento diferente:

Starting initialization...Ok.
Checking init scripts...Ok.

Como posso obter algo assim:

Starting initialization...       Ok.
Checking init scripts...         Ok.
psihodelia
fonte

Respostas:

157

Você pode especificar a largura em campos de string, por exemplo

printf("%-20s", "initialization...");

e então tudo o que for impresso com esse campo será preenchido em branco com a largura que você indicar.

O -justifica à esquerda seu texto nesse campo.

Carl Smotricz
fonte
130
Infelizmente, não sou inteligente o suficiente para contar tão alto. No entanto, confio que o autor da pergunta seja inteligente o suficiente para extrapolar meu exemplo :)
Carl Smotricz
3
que tal justificado à direita? Não existem bandeiras mencionadas em K&R
Ungeheuer
9
Justificado à direita é o padrão. Sem um -, seus dados serão justificados à direita em um campo cuja largura você especificou.
Carl Smotricz,
24

printfpermite a formatação com especificadores de largura. por exemplo


printf( "%-30s %s\n", "Starting initialization...", "Ok." );

Você usaria um especificador de largura negativa para indicar justificação à esquerda, porque o padrão é usar justificação à direita.

PP.
fonte
18

Além disso, se desejar a flexibilidade de escolher o width, você pode escolher entre um dos dois formatos a seguir (com ou sem truncamento):

int width = 30;
//no truncation uses %-*s
printf( "%-*s %s\n", width, "Starting initialization...", "Ok." );
// output is "Starting initialization...     Ok."

//truncated to the specified width uses %-.*s
printf( "%-.*s %s\n", width, "Starting initialization...", "Ok." ); 
// output is "Starting initialization... Ok."
equilíbrio de vida
fonte
13

Também existe o %nmodificador que pode ajudar em certas circunstâncias. Ele retorna a coluna em que a string estava até agora. Exemplo: você deseja escrever várias linhas que estão dentro da largura da primeira linha como uma tabela.

int width1, width2;
int values[6][2];
printf("|%s%n|%s%n|\n", header1, &width1, header2, &width2);

for(i=0; i<6; i++)
   printf("|%*d|%*d|\n", width1, values[i][0], width2, values[i][1]);

imprimirá 2 colunas da mesma largura de qualquer comprimento que as duas strings header1e header2possam ter. Não sei se todas as implementações têm o, %nmas o Solaris e o Linux têm.

Patrick Schlüter
fonte
Esta solução funciona, mas qualquer pessoa que pegar isso e colocá-la em seu código deve estar ciente do risco de introduzir vulnerabilidades de memória .
Matthew Cole
0

Há também a solução de baixa tecnologia de contar espaços adicionando manualmente para alinhar suas mensagens. Nada impede que você inclua alguns espaços à direita em suas strings de mensagem.

Carl Smotricz
fonte
-2

Comece com o uso de Tabs, o modificador de caractere \ t . Ele avançará para um local fixo (colunas, linguagem de terminal). No entanto, não ajuda se houver diferenças maiores do que a largura da coluna (4 caracteres, se bem me lembro).

Para corrigir isso, escreva seu "OK / NOK" usando um número fixo de Abas (5? 6 ?, tente), então retorne ( \ r ) sem new-lining e escreva sua mensagem.

jpinto3912
fonte
5
Sempre existe o perigo de que uma string seja mais longa do que uma parada de tabulação, forçando assim a tabulação e o texto resultantes a ficarem desalinhados.
PP.
Na verdade, não ... primeiro escreva a tabulação OK / NOK, depois / r, agora escreva a frase, agora / n. A frase pode substituir o OK / NOK. Mas o seu jeito é muito melhor, eu não sabia sobre justificativa negativa.
jpinto3912