views:

145

answers:

7

I tried the search function but only found questions regarding reading in comma/space delimited files.

My question is however, how do you usually approach this. Say I have a list/array/... of values, like {1, 2, 3, 4} and want to print them with a delimiter.

The simplest version would be something like:

#include <stdio.h>

int main(void)
{
     char list[] = {1, 2, 3, 4};
     unsigned int i;

     for (i = 0; i < 4; ++i)
     printf("%d, ", list[i]);

     return 0;
}

which will obviously print "1, 2, 3, 4, ". The problem I have with that is the comma and space character at the end.

Now I could do:

#include <stdio.h>

int main(void)
{
    char list[] = {1, 2, 3, 4};
    unsigned int i;

    for (i = 0; i < 4; ++i)
    {
        printf("%d", list[i]);
        if (i < 3)
            printf(", ");
    }

    return 0;
}

Bút that doesn't seem like the best way to do it. Can somebody point me into the right direction? Thanks

PS: No, I don't usually hardcode values
PPS: No, I am not trying to write .csv files ;)

+4  A: 

I use this idiom:

assert(n > 0);
printf("%d", list[0]);
for (i = 1; i < n; ++i)
     printf(", %d", list[i]);

Its one disadvantage is that it doesn't scale nicely for n == 0, like a simple loop. Alternatively, you can add protection against n == 0:

if (n > 0)
    printf("%d", list[0]);
for (i = 1; i < n; ++i)
     printf(", %d", list[i]);
Michał Trybus
Thank you, this looks very nice and tidy.
melzer
Another disadvantage is that you have to duplicate the body of the loop.
jamesdlin
The `assert(n > 0);` does not look right, that's not a necessary condition to print contents of an array.
ArunSaha
For this code it is. Underneath is the other version.
Michał Trybus
You could quite reasonably replace the `assert()` by `if (n > 0) {` followed by the other code and `}`.
Jonathan Leffler
A: 

Use Michal Trybus's version or the reverse

for (i = 0; i < (n - 1); ++i) 
{
     printf("%d, ", list[i]);
}
printf("%d", list[n - 1]);
Himanshu
@Michal, Nice catch. thank you very much.
Himanshu
No problem. I've removed this comment already;)
Michał Trybus
+11  A: 

My standard technique for this is:

const char *pad = "";
for (int i = 0; i < n; i++)
{
    printf("%s%d", pad, list[i]);
    pad = ", ";
}

Sometimes, the initial value of pad is a blank, or a colon blank, or whatever else works in context.

Jonathan Leffler
Pretty unusual, I like it. +1
Michał Trybus
Unusual indeed, but a very nice idea. But I think I will stick with Michal Trybus version.
melzer
A: 
for ( printf("%d",list[i=0]) ; i < n ; printf(", %d", list[++i]) ) ;
I wanted to upvote, because this reminds me of my C lecturer. She loved code nobody can understand. Unfortunately, off-by-one;(
Michał Trybus
+2  A: 

I picked up this format with the conditional operator from K&R2:

for (i = 0; i < n; i++)
    printf("%d%s", list[i], i+1 < n ? ", " : "\n");
schot
melzer
@melzer: Yes, the second edition of "The C Programming Language" with the "ANSI C" stamp on the front. I just looked it up: it is used in section 5.10.
schot
+1  A: 

Well even thought there is already an accepted answer, nobody has come with the obvious one to my taste:

#include <stdio.h>
int main(void) {
    unsigned list[] = {1, 2, 3, 4};
    unsigned const n = 4;
    if (n) for (unsigned i = 0; ; ++i) {
        printf("%d", list[i]);
        if (i >= n) break;
        printf(", ");
    }
    printf("\n");
    return 0;
}
Jens Gustedt
That's pretty much the same as what the OP mentioned.
jamesdlin
@jamesdlin: I don't know how you measure "pretty much", but the idea is to do just the number of comparisons that are needed, without redundancy. On the other hand it avoids the duplication of the number printing code as in Michał Trybus' solution.
Jens Gustedt
Oh, good point. I missed that aspect. You do have to add an extra check if the list might be empty, though.
jamesdlin
@jamesdlin: yes, good point, too. I'll add that.
Jens Gustedt
A: 

Why not just another version while we're at it. Here's what I normally do

for (i=0;i<n;++i)
{
  if (i) printf(", ");
  printf("%d",list[i]);
}
miked