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) {
    strcpy(paddedLine,lineToPad);
    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
    printf.

    Identical output. Nice!

    C is pretty cool... when it's not beating you up.
     
    DFS, Jun 12, 2014
    #1
    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
     
    Jorgen Grahn, Jun 12, 2014
    #2
    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
    #3
  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
    #4
  5. DFS

    Ken Brody Guest

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

    Yes, I have legacy code with stuff like:

    sprintf(formatbuffer,"%%%ds",length);
    sprintf(resultbuffer,formatbuffer,string);
     
    Ken Brody, Jun 13, 2014
    #5
  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
    #6
  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
    #7
  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
     
    Jorgen Grahn, Jun 14, 2014
    #8
  9. Quibble: K&R1 was published in 1978.
     
    Keith Thompson, Jun 14, 2014
    #9
  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
    #10
  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
    #11
  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
    #12
    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.