tags:

views:

135

answers:

4

I would like to use the syntax that printf uses, using the %d, %s and adding values after to assign a value to a char[]. Is this possible?

e.g. Given an output of:

printf("now: %d-%d-%d %d:%d:%d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);

I'd like to assign that to char[] output;

How can this be done?

I tried:

sprintf(output, "now: %d-%d-%d %d:%d:%d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);

but that didn't seem to work. Is sprintf used differently... or is that not what I should be using?

Thanks!

EDIT: It turned out I simply needed to increase the initialized length of output...

+1  A: 

So long as output has enough space your syntax should work.

output = (char *)malloc( 1000 ); //or some other large enough number
sprintf( output, control string, . . . );

and you should be fine.

Mimisbrunnr
+2  A: 

That should work fine provided you have enough space in the output buffer (at least 26 bytes) to take the largest string you'll create:

char output[26];
sprintf(output, "now: %d-%d-%d %d:%d:%d\n",
    tm.tm_year + 1900,
    tm.tm_mon + 1,
    tm.tm_mday,
    tm.tm_hour,
    tm.tm_min,
    tm.tm_sec);

You need:

  • 5 for "now: ".
  • 4 for the year (for at least the next 79 centuries).
  • 2 each for the other five numerics.
  • 5 for the separators ("-- ::").
  • 1 for the newline.
  • 1 for the terminating null character.

You may also want to consider changing the format string to "now: %04d-%02d-%02d %02d:%02d:%02d" so that the datetimes will line up if you're outputting them, to avoid something like:

2009-12-31 23:59:58 blah blah blah
2010-1-1 0:0:7 yada yada yada

when

2009-12-31 23:59:58 blah blah blah
2010-01-01 00:00:07 yada yada yada

looks so much better. You'll notice I've left the "\n" off the end - since this is the sort of code you see a lot in logging, you'd want the datetime to be in a format you could easily append to, something like:

fprintf (logFile, "%s Cannot write to '%s', error = %d\n",
    output, fileSpec, errno);

If I've misunderstood what you're using this for, feel free to ignore the last few paragraphs.

paxdiablo
A: 

Just a note: many modern C runtime libraries implement the "scprintf" (or "_scprinf") function, that returns the number of characters that would be generated by sprintf with the same format and arguments (e.g. here the description of Microsoft Implementation). The main problem is that the format/parameters evaluation is done twice, with a considerable performace loss. If it's not a problem for you, you can use the value returned by scprinf to dynamically allocate a buffer of the required size. Also, as optimization, you can recycle the allocated buffer to reduce the frequency of allocations (they indeed tend to zero). Example (NOTE: multithreading issues ignored here)

int nchr;
static int last_size = 0;
static char *buff = NULL;
char *new_buff;

nchr = _scprintf(format, /* ...args... */) + 1;
if (last_size < nchr) {
     new_buff = malloc(nchr);
     if (new_buff == NULL) { /* ERROR... */ }
     if (buff != NULL) {
           free(buff);
     }
     buff = new_buff;
     last_size = nchr;
}
sprinf(buff, format, /* ...args... */);
Giuseppe Guerrini
+1  A: 

Just to be on the safe side I suggest using snprintf instead of sprintf. This will keep you away from the nasty surprises.

http://libslack.org/manpages/snprintf.3.html

Vlad