You gotta love printf

Discussion in 'C Programming' started by DFS, Jun 12, 2014.

  1. DFS

    DFS Guest

    I wanted to pad a line out to length N (say 25) and add a visual cue,
    like so:

    Pad this long line to 25 |
    Pad this line to 25 |
    Pad this to 25 |

    So I wrote:

    char *padToEnd(const char *lineToPad, char *paddedLine, int lineLen) {
    for (int i = 1; i <= (lineLen - (strlen(lineToPad) + 1)); i++) {
    strncat(paddedLine, " ", 1);
    strncat(paddedLine, "|", 1);
    return paddedLine;

    Then I found:

    printf("%-*s|\n", lineLen, lineToPad);

    where * lets you substitute the value for line length, right into the

    Identical output. Nice!

    C is pretty cool... when it's not beating you up.
    DFS, Jun 12, 2014
    1. Advertisements

  2. DFS

    Jorgen Grahn Guest

    Yes; people should reread the printf documentation once in a while.
    Only recently I discovered that you can make printf truncate strings,
    e.g. "%-4.5s".

    That one (and the * you mentioned) has enabled me to eliminate a lot
    of fragile code which reimplemented the same features.

    Printing pointers using %p seems to be another thing a lot of people
    are unaware of.

    Jorgen Grahn, Jun 12, 2014
    1. Advertisements

  3. And a lot of people who know about %p don't seem to know that it
    specifically requires a void* argument; pointers of other types should
    be cast to void*:

    int n = 42;
    printf("&n = %p\n", &n); // Probably works, but undefined behavior
    printf("&n = %p\n", (void*)*n); // Better

    (An argument of type char*, signed char*, or unsigned char* will almost
    certainly work, but I still prefer the explicit cast; it makes for one
    less thing to have to think about.)
    Keith Thompson, Jun 12, 2014
  4. [...]

    No, the use of '*' as a field width is included in C89/C90. (It's not
    in K&R1.)
    Keith Thompson, Jun 12, 2014
  5. DFS

    Ken Brody Guest

    On 6/12/2014 1:58 PM, Nick Bowler wrote:

    Yes, I have legacy code with stuff like:

    Ken Brody, Jun 13, 2014
  6. DFS

    DFS Guest

    But, printf will only pad with 0 or space, whereas my little function
    can pad with anything:

    Pad this long line to 25--|
    Pad this line to 25-------|
    Pad this to 25------------|

    Pad this long line to 25__|
    Pad this line to 25_______|
    Pad this to 25____________|
    DFS, Jun 13, 2014
  7. Blimey! How old is that code? The * format only just missed being in
    K&R1 (1979). It is documented in the V7 man page which seems to be
    copyright 1979. I don't think I ever used a C library without it, but I
    didn't say hi to C until 1980.
    Ben Bacarisse, Jun 14, 2014
  8. DFS

    Jorgen Grahn Guest

    That was my point upthread: people (myself included) seem to prefer to
    write convoluted code like that, to reading the printf manual page.

    Jorgen Grahn, Jun 14, 2014
  9. Quibble: K&R1 was published in 1978.
    Keith Thompson, Jun 14, 2014
  10. Yes, thanks. I ended up typing the same date twice. Had I done so
    thrice, the whole thing would have been garbled beyond any sense.
    Ben Bacarisse, Jun 14, 2014
  11. DFS

    Ken Brody Guest

    Well, it's not in any "recent" code, but I have seen it in code that's been
    around since TRS-Xenix on the Tandy Model 16. (ie: early 1980's.) It
    wasn't in K&R1, and it might not have been in the TRS-Xenix manuals, either.
    Ken Brody, Jun 16, 2014
  12. The TRS-Xenix manual does have it, but code gets copied about so it may
    well pre-date Xenix. And there's always that point that people just
    don't read manuals.
    Ben Bacarisse, Jun 16, 2014
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.