8

As of now I'm using below line to print with out dot's

fprintf( stdout, "%-40s[%d]", tag, data);

I'm expecting the output would be something like following,

Number of cards..................................[500]
Fixed prize amount [in whole dollars]............[10]
Is this a high winner prize?.....................[yes]

How to print out dash or dot using fprintf/printf?

7 Answers 7

10

A faster approach:

If the maximum amount of padding that you'll ever need is known in advance (which is normally the case when you're formatting a fixed-width table like the one you have), you can use a static "padder" string and just grab a chunk out of it. This will be faster than calling printf or cout in a loop.

static const char padder[] = "......................"; // Many chars

size_t title_len = strlen(title);
size_t pad_amount = sizeof(padder) - 1 - title_len;

printf(title); // Output title

if (pad_amount > 0) {
    printf(padder + title_len); // Chop!
}

printf("[%d]", data);

You could even do it in one statement, with some leap of faith:

printf("%s%s[%d]", title, padder + strlen(title), data);
Sign up to request clarification or add additional context in comments.

4 Comments

your last suggestion breaks if strlen(title) > strlen(padder)
@Christoph, hence the proclaimed "leap of faith" :)
@Ates: interesting concept, this 'faithful programming' of yours ;)
size_t -> int is required in if ((int)pad_amount > 0)
9

You can easily do this with iostreams instead of printf

cout << setw(40) << setfill('.') << left << tag[i] << '[' << data[i] << ']' << endl;

Or if you really need to use fprintf (say, you are passed a FILE* to write to)

strstream str;
str << setw(40) << setfill('.') << left << tag[i] << '[' << data[i] << ']' << endl;
printf(%s", str.str());

1 Comment

+1 for being easy to read and understand and not breaking under certain (albeit somewhat uncommon situations).
3

You can't do it in one statement. You can use sprintf, then substitute dots for spaces yourself, or do something like

int chars_so_far;
char padder[40+1]= '..........'; //assume this is 40 dots.
printf("%.40s%n",tag,&chars_so_far);
printf("%s[%d]",padder+chars_so_far,data);

Edit: Simplified my example above based on @Ates' padder concept. This way doesn't require any 'leaps of faith', about whether the tag string is too big or too small - it always starts the data in column 41.

1 Comment

@Ates: it could, but imo not without two calls to strlen() if you want to properly check boundaries - therefore, you need to cache this value -> two statements!
2

You are going to have to output the string with the dot or dash padding yourself.

Something like (forgive my C, it's rusty):

printAmount(char *txt, int amt) {
    printf("%s",txt);
    for(int xa=strlen(txt); xa<40; xa++) { putc('.'); }
    printf("[%d]",amt);
    printf("\n");
    }

Comments

2

Another solution using a tiny helper function

static inline size_t min(size_t a, size_t b)
{
    return a < b ? a : b;
}

Then, you can do the following:

char padder[] = "........................................";
int len = min(strlen(tag), sizeof(padder) - 1);
printf("%.*s%s[%d]", len, tag, padder + len, data);

This is essentially what Ates posted, but I actually figured this out on my own ;)

2 Comments

Change the size_t to int; you must pass an int to the '*' in the printf() family of functions.
Or make the helper more helpful: printf("%s%s[%d]", title, getPadding(title), data);
1

I'd suggest writing a function that pads a string with X characters and use that to generate the first argument to your printf string. Something like:

char s[40];
pad_str(tag, s, 40, '.');
fprintf( stdout, "%-40s[%d]", s, data);

Note that the third line of your sample data would need this format:

"%-40s[%s]"

1 Comment

This makes the most sense. If you are padding to a fixed amount of characters, you probably want to chop titles that are too long, so it makes sense to use fixed-width arrays.
0

I think there's a better way.

#include <string.h>
#include <stdio.h>

#define MIN(A,B) ((A)<(B)?(A):(B))
char *dashpad(char *buf, int len, const char *instr) {
    memset(buf, '-', len);
    buf[len] = 0;
    int inlen = strlen(instr);
    memcpy(buf, instr, MIN(len, inlen));
    return buf;
}
main() {
    char buf[40];
    printf("%s\n", dashpad(buf, 40, "Hello world, dash padded "));
}

5 Comments

First filling the entire buffer with the pad character, and then overwriting them seems a bit wasteful though...
Also, you have a buffer overrun (don't you love C) - s/be: buf[len-1]=0;
And you have a null-erasure bug in you min(), which should also be len-1.
is it possible to call a function inside printf?
@Thi: Yes this is legitimate - the function is invoked and it's return passed as a parameter to printf... this is normal coding in any procedural, OOP or functional language.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.