108

I have the following statement:

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

I want to break it up. I tried the following but it doesn't work.

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

How can I break it up?

dbush
  • 205,898
  • 23
  • 218
  • 273
neuromancer
  • 53,769
  • 78
  • 166
  • 223
  • 1
    Some good suggestions given, but neither of them may be as clear or maintainable as just four separate printf() calls. – Clifford Nov 17 '09 at 23:45
  • @Clifford: then you could write C++ so cout looks better for you. – Test Nov 18 '09 at 07:17

5 Answers5

210

If you want to break a string literal onto multiple lines, you can concatenate multiple strings together, one on each line, like so:

printf("name: %s\t"
"args: %s\t"
"value %d\t"
"arraysize %d\n", 
sp->name, 
sp->args, 
sp->value, 
sp->arraysize);
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 110
    just commenting to explain the little-known C fact that whitespace between two strings is concatenation. – Brian Postow Nov 17 '09 at 22:00
  • 2
    @Lundin Having each variable and its value clearly represented on its own line is much easier to read for me. Can you imagine a debugger in an IDE that put all variables and values onto a single line? I can't. _(Yes, I know it doesn't put new-line characters between each string, but I'm comparing the readibility of the source code to the readibility of variables in a debugger)_ – byxor Jul 11 '17 at 16:33
  • 2
    Is this concatenation made by the preprocessor? – debuti Dec 05 '17 at 15:07
35

The C compiler can glue adjacent string literals into one, like

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

The preprocessor can use a backslash as a last character of the line, not counting CR (or CR/LF, if you are from Windowsland):

printf("foo %s \
bar: %d", foo, bar);
gkb0986
  • 3,099
  • 1
  • 24
  • 22
qrdl
  • 34,062
  • 14
  • 56
  • 86
  • 6
    The first has already been suggested, the second suffers from the fact that it breaks if there is any whitespace *after* the '\'; a bug that can be baffling when it occurs. – Clifford Nov 17 '09 at 23:43
  • 1
    Neither of those two examples have anything at all to do with the C preprocessor. – Dan Moulding Nov 18 '09 at 05:15
  • @Dan my cpp seems to understand / (see my edit above). I'm not sure if this is standard behavior. – sigjuice Nov 18 '09 at 07:12
  • @Dan While joining adjacent literals may be performed with either preprocessor or compiler (at it last stage before actual compilation), handling line continuation is performed by preprocessor, because otherwise multiline macros cannot be implemented. Also see here - http://gcc.gnu.org/onlinedocs/cpp/Initial-processing.html – qrdl Nov 18 '09 at 08:23
  • @sigjuice It is a standard behaviour so your edit is superfluous – qrdl Nov 18 '09 at 08:25
  • 2
    @qrdl: My bad, you are right about the second one. Line continuation is always done by the preprocessor. Sometimes I need to be reminded that I'm *not* a know-it-all ;) I do still think that in the normal case the compiler joins string literals, though. – Dan Moulding Nov 18 '09 at 18:40
  • @qrdl That edit was more of a discussion of one of the points raised by @Dan. – sigjuice Nov 21 '09 at 20:43
21

Just some other formatting options:

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

You can add variations on the theme. The idea is that the printf() conversion speficiers and the respective variables are all lined up "nicely" (for some values of "nicely").

pmg
  • 106,608
  • 13
  • 126
  • 198
  • Nothing functional here, but a novel idea I've never seen before. I like it, great comment @pmg! – rpj Nov 19 '09 at 03:07
6

The de-facto standard way to split up complex functions in C is per argument:

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

Or if you will:

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

You shouldn't split up the string, nor should you use \ to break a C line. Such code quickly turns completely unreadable/unmaintainable.

Lundin
  • 195,001
  • 40
  • 254
  • 396
4

I don't think using one printf statement to print string literals as seen above is a good programming practice; rather, one can use the piece of code below:

printf("name: %s\t",sp->name);
printf("args: %s\t",sp->args);
printf("value: %s\t",sp->value);
printf("arraysize: %s\t",sp->name); 
helencrump
  • 1,351
  • 1
  • 18
  • 27