En C, ¿se puede dividir una declaración printf larga en varias líneas?

86

Tengo la siguiente declaración:

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

Quiero romperlo. Intenté lo siguiente pero no funciona.

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

¿Cómo puedo romperlo?

neuromante
fuente
1
Se dan algunas buenas sugerencias, pero ninguna de ellas puede ser tan clara o fácil de mantener como solo cuatro llamadas independientes a printf ().
Clifford
@Clifford: entonces podrías escribir C ++ para que cout se vea mejor para ti.
Prueba el

Respuestas:

173

Si desea dividir un literal de cadena en varias líneas, puede concatenar varias cadenas juntas, una en cada línea, así:

printf("name: %s\t"
"args: %s\t"
"value %d\t"
"arraysize %d\n", 
sp->name, 
sp->args, 
sp->value, 
sp->arraysize);
James McNellis
fuente
85
solo comentando para explicar el hecho poco conocido de C de que el espacio en blanco entre dos cadenas es una concatenación.
Brian Postow
2
@Lundin Tener cada variable y su valor claramente representados en su propia línea es mucho más fácil de leer para mí. ¿Te imaginas un depurador en un IDE que coloque todas las variables y valores en una sola línea? No puedo. (Sí, sé que no pone caracteres de nueva línea entre cada cadena, pero estoy comparando la legibilidad del código fuente con la legibilidad de las variables en un depurador)
byxor
¿Esta concatenación la realiza el preprocesador?
debuti
21

El compilador de C puede pegar cadenas literales adyacentes en una, como

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

El preprocesador puede usar una barra invertida como último carácter de la línea, sin contar CR (o CR / LF, si es de Windowsland):

printf("foo %s \
bar: %d", foo, bar);
qrdl
fuente
6
El primero ya ha sido sugerido, el segundo adolece del hecho de que se rompe si hay algún espacio en blanco después de la '\'; un error que puede resultar desconcertante cuando ocurre.
Clifford
1
Ninguno de esos dos ejemplos tiene nada que ver con el preprocesador de C.
Dan Moulding
@Dan mi cpp parece entender / (vea mi edición arriba). No estoy seguro de si este es un comportamiento estándar.
sigjuice
@Dan Si bien la unión de literales adyacentes se puede realizar con el preprocesador o el compilador (en la última etapa antes de la compilación real), el preprocesador realiza el manejo de la continuación de línea, porque de lo contrario no se pueden implementar macros multilínea. Vea también aquí - gcc.gnu.org/onlinedocs/cpp/Initial-processing.html
qrdl
2
@qrdl: Vaya, tienes razón sobre el segundo. La continuación de la línea siempre la realiza el preprocesador. A veces necesito que se les recuerde que soy no un sabe-lo-todo;) Yo sigo pensando que en el caso normal el compilador se une a los literales de cadena, sin embargo.
Dan Moulding
20

Solo algunas otras opciones de formato:

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);

Puede agregar variaciones sobre el tema. La idea es que los especialistas de printf()conversión y las variables respectivas estén alineados "bien" (para algunos valores de "bien").

pmg
fuente
Nada funcional aquí, pero una idea novedosa que nunca había visto antes. Me gusta, gran comentario @pmg!
rpj
3

La forma estándar de facto de dividir funciones complejas en C es por argumento:

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

O si quieres:

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

No debes dividir la cadena, ni debes usar \para romper una línea C. Dicho código rápidamente se vuelve completamente ilegible / inmantenible.

Lundin
fuente
3

No creo que usar una printfdeclaración para imprimir cadenas literales como se ve arriba sea una buena práctica de programación; más bien, uno puede usar el fragmento de código a continuación:

printf("name: %s\t",sp->name);
printf("args: %s\t",sp->args);
printf("value: %s\t",sp->value);
printf("arraysize: %s\t",sp->name); 
antoine maboula
fuente