Em C, uma instrução printf longa pode ser dividida em várias linhas?


86

Tenho a seguinte declaração:

printf("name: %s\targs: %s\tvalue %d\tarraysize %d\n", sp->name, sp->args, sp->value, sp->arraysize);

Eu quero acabar com isso. Tentei o seguinte, mas não funcionou.

printf("name: %s\t
args: %s\t
value %d\t
arraysize %d\n", 
sp->name, 
sp->args, 
sp->value, 
sp->arraysize);

Como posso separar?


1
Algumas boas sugestões foram dadas, mas nenhuma delas pode ser tão clara ou sustentável como apenas quatro chamadas separadas de printf ().
Clifford

@Clifford: então você poderia escrever C ++ para que cout ficasse melhor para você.
Teste de

Respostas:


173

Se quiser quebrar um literal de string em várias linhas, você pode concatenar várias strings, uma em cada linha, assim:

printf("name: %s\t"
"args: %s\t"
"value %d\t"
"arraysize %d\n", 
sp->name, 
sp->args, 
sp->value, 
sp->arraysize);

85
apenas comentando para explicar o fato pouco conhecido de C de que o espaço em branco entre duas strings é concatenação.
Brian Postow

2
@Lundin Ter cada variável e seu valor claramente representado em sua própria linha é muito mais fácil de ler para mim. Você pode imaginar um depurador em um IDE que coloque todas as variáveis ​​e valores em uma única linha? Eu não posso. (Sim, eu sei que não coloca caracteres de nova linha entre cada string, mas estou comparando a legibilidade do código-fonte com a legibilidade das variáveis ​​em um depurador)
byxor

Essa concatenação é feita pelo pré-processador?
estreia em

21

O compilador C pode colar literais de string adjacentes em um, como

printf("foo: %s "
       "bar: %d", foo, bar);

O pré-processador pode usar uma barra invertida como último caractere da linha, sem contar CR (ou CR / LF, se você for do Windowsland):

printf("foo %s \
bar: %d", foo, bar);

6
O primeiro já foi sugerido, o segundo sofre pelo fato de quebrar se houver algum espaço em branco após o '\'; um bug que pode ser desconcertante quando ocorre.
Clifford

1
Nenhum desses dois exemplos tem nada a ver com o pré-processador C.
Dan Molding

@Dan meu cpp parece entender / (veja minha edição acima). Não tenho certeza se esse é o comportamento padrão.
sigjuice

@Dan Embora a junção de literais adjacentes possa ser executada com o pré-processador ou compilador (no último estágio antes da compilação real), o tratamento da continuação da linha é executado pelo pré-processador, porque caso contrário macros multilinhas não podem ser implementadas. Veja também aqui - gcc.gnu.org/onlinedocs/cpp/Initial-processing.html
qrdl

2
@qrdl: Que pena, você está certo sobre o segundo. A continuação da linha é sempre feita pelo pré-processador. Às vezes eu preciso ser lembrado que eu sou não um know-it-all;) Eu ainda acho que no caso normal o compilador junta strings literais, no entanto.
Dan Molding

20

Apenas algumas outras opções de formatação:

printf("name: %s\targs: %s\tvalue %d\tarraysize %d\n", 
        a,        b,        c,        d);

printf("name: %s\targs: %s\tvalue %d\tarraysize %d\n", 
              a,        b,        c,            d);

printf("name: %s\t"      "args: %s\t"      "value %d\t"      "arraysize %d\n", 
        very_long_name_a, very_long_name_b, very_long_name_c, very_long_name_d);

Você pode adicionar variações sobre o tema. A ideia é que os printf()speficiers de conversão e as respectivas variáveis ​​estejam todos alinhados "bem" (para alguns valores de "bem").


Nada funcional aqui, mas uma ideia nova que nunca vi antes. Eu gosto, ótimo comentário @pmg!
rpj

3

A maneira padrão de fato para dividir funções complexas em C é por argumento:

printf("name: %s\targs: %s\tvalue %d\tarraysize %d\n", 
       sp->name, 
       sp->args, 
       sp->value, 
       sp->arraysize);

Ou se você:

const char format_str[] = "name: %s\targs: %s\tvalue %d\tarraysize %d\n";
...
printf(format_str, 
       sp->name, 
       sp->args, 
       sp->value, 
       sp->arraysize);

Você não deve dividir a string, nem deve usar \para quebrar uma linha C. Esse código rapidamente se torna completamente ilegível / impossível de manter.


3

Não acho que usar uma printfinstrução para imprimir literais de string como visto acima seja uma boa prática de programação; em vez disso, pode-se usar o trecho de código abaixo:

printf("name: %s\t",sp->name);
printf("args: %s\t",sp->args);
printf("value: %s\t",sp->value);
printf("arraysize: %s\t",sp->name); 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.