Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining sprintf buffer size - what's the standard?

Tags:

c

int

printf

When converting an int like so:

char a[256]; sprintf(a, "%d", 132); 

what's the best way to determine how large a should be? I assume manually setting it is fine (as I've seen it used everywhere), but how large should it be? What's the largest int value possible on a 32 bit system, and is there some tricky way of determining that on the fly?

like image 382
Dominic Bou-Samra Avatar asked Oct 13 '10 00:10

Dominic Bou-Samra


People also ask

How do you calculate buffer size?

To check the buffer window, multiply the bit rate (bits per second) by the buffer window (in seconds) and divide by 1000 to get the size, in bits, of the buffer for the stream.

What is sprintf in c?

sprintf() in C sprintf stands for "string print". In C programming language, it is a file handling function that is used to send formatted output to the string. Instead of printing on console, sprintf() function stores the output on char buffer that is specified in sprintf.

What is the difference between Sprintf and Snprintf?

The snprintf function is similar to sprintf , except that the size argument specifies the maximum number of characters to produce. The trailing null character is counted towards this limit, so you should allocate at least size characters for the string s .

How big is a buffer?

The most common buffer size settings you'll find in a DAW are 32, 64, 128, 256, 512, and 1024.


2 Answers

Some here are arguing that this approach is overkill, and for converting ints to strings I might be more inclined to agree. But when a reasonable bound for string size cannot be found, I have seen this approach used and have used it myself.

int size = snprintf(NULL, 0, "%d", 132); char * a = malloc(size + 1); sprintf(a, "%d", 132); 

I'll break down what's going on here.

  1. On the first line, we want to determine how many characters we need. The first 2 arguments to snprintf tell it that I want to write 0 characters of the result to NULL. When we do this, snprintf won't actually write any characters anywhere, it will simply return the number of characters that would have been written. This is what we wanted.
  2. On the second line, we are dynamically allocating memory to a char pointer. Make sure and add 1 to the required size (for the trailing \0 terminating character).
  3. Now that there is enough memory allocated to the char pointer, we can safely use sprintf to write the integer to the char pointer.

Of course you can make it more concise if you want.

char * a = malloc(snprintf(NULL, 0, "%d", 132) + 1); sprintf(a, "%d", 132); 

Unless this is a "quick and dirty" program, you always want to make sure to free the memory you called with malloc. This is where the dynamic approach gets complicated with C. However, IMHO, if you don't want to be allocating huge char pointers when most of the time you will only be using a very small portion of them, then I don't think this is bad approach.

like image 167
Daniel Standage Avatar answered Sep 28 '22 10:09

Daniel Standage


It's possible to make Daniel Standage's solution work for any number of arguments by using vsnprintf which is in C++11/C99.

int bufferSize(const char* format, ...) {     va_list args;     va_start(args, format);     int result = vsnprintf(NULL, 0, format, args);     va_end(args);     return result + 1; // safe byte for \0 } 

As specified in c99 standard, section 7.19.6.12 :

The vsnprintf function returns the number of characters that would have been written had n been sufficiently large, not counting the terminating null character, or a negative value if an encoding error occurred.

like image 41
Regis Portalez Avatar answered Sep 28 '22 11:09

Regis Portalez