64566

Buffer size for converting unsigned long to string

In reference to question and the answer here: Can I use this method so that the solution will be platform independent.

char *buff = (char*) malloc(sizeof(unsigned long)*8); sprintf(buff, "%lu", unsigned_long_variable);

Here I am getting the value of buffer length as it will similar to unsigned long variable. Is this approach correct?

Answer1:

You want to know how many characters are needed to represent the largest possible unsigned long. Correct?

To that end, you are trying to calculate the largest possible unsigned long:

sizeof(unsigned long)*8

That is faulty in several ways. For one, sizeof returns multiples of char, which need not be 8 bit. You should multiply with CHAR_BIT (from <limits.h>) instead. But even that is not necessary, because that very same header already does provide the largest possible value -- UCHAR_MAX.

Then you're making a mistake: Your calculation gives the size of the integer representation of unsigned long in bits. What you want is the size of the string representation in characters. This can be achieved with the log10() function (from <math.h>):

log10( UCHAR_MAX )

This will give you a double value that indicates the number of (decimal) digits in UCHAR_MAX. It will be a fraction, which you need to round up (1) (ceil() does this for you).

Thus:

#include <math.h> #include <stdlib.h> #include <limits.h> int main() { char * buff = malloc( ceil( log10( UCHAR_MAX ) ) + 1 ); //... }

All in all, this is quite dodgy (I made two mistakes while writing this out, shame on me -- if you make mistakes when using this, shame on you). And it requires the use of the math library for something that snprintf( NULL, ... ) can do for you more easily, as indicated by the Q&A you linked to.

<hr>

(1): log10( 9999 ) gives 3.9999565... for the four-digit number.

Answer2:

Don't even try to calculate the buffer size.

Start with snprintf, which will tell you safely how many characters are needed. Then you know how many bytes to allocate to print safely.

Since this is a few lines of code that you don't want to repeat again and again, write a function malloc_printf that does exactly what you want: In that function, call snprintf with a NULL destination, then malloc the buffer, sprintf into the malloc buffer, and return it. To make it faster and to often avoid two snprintf and sprintf calls, write into a buffer of 256 chars first which is often enough.

So your final code would be

char* buff = malloc_printf ("%lu", unsigned_long_variable);

Also does quick, safe and easy string concatenation using the format %s%s, for example.

Answer3:

The C standard doesn't put an upper limit to the number of bits per char.

If someone constructs a C compiler that uses for example 2000 bits per char the output can overflow the buffer.

Instead of 8 you should use CHAR_BIT from limits.h.

Also, note that you need (slighly less than) 1 char per 3 bits and you need 1 byte for the string terminator.

So, something like this:

#include <limit.h> char *buff = malloc(1 + (sizeof(unsigned long) * CHAR_BIT + 2) / 3); sprintf(buff, "%lu", unsigned_long_variable);

Answer4:

No, this is not the right way to calculate the buffer size.

E.g. for 4 byte unsigned longs you have values up to 2^32-1 which means 10 decimal digits. So your buffer needs 11 chars.

You are allocating 4 * 8 = 32.

The correct formula is

ceil(log10(2^(sizeof(unsigned long) * CHAR_BIT) - 1)) + 1

(log10 denotes the decimal logarithm here)

A good (safe) estimation is:

(sizeof(unsigned long) * CHAR_BIT + 2) / 3 + 1

because log10(2) is less than 0.33.

Answer5:

Short answer:

#define INTEGER_STRING_SIZE(t) (sizeof (t) * CHAR_BIT / 3 + 3) unsigned long x; char buf[INTEGER_STRING_SIZE(x)]; int len = snprintf(buf, sizeof buf, "%lu", x); if (len < 0 || len >= sizeof buf) Handle_UnexpectedOutput(); <hr>

OP's use of sizeof(unsigned long)*8 is weak. On systems where CHAR_BIT (the # of bits per char) is large (it must be at least 8), sizeof(unsigned long) could be 1. 1*8 char is certainly too small for 4294967295 (the minimum value for ULONG_MAX).

Concerning: sprintf()/snprintf() Given locale issues, in theory, code may print additional characters like 4,294,967,295 and so exceed the anticipated buffer. Unless very tight memory constraints occur, recommend a 2x anticipated sized buffer.

char buf[ULONG_STRING_SIZE * 2]; // 2x int len = snprintf(buf, sizeof buf, "%lu", x);

The expected maximum string width of printing some unsigned integer is ceil(log10(unsigned_MAX)) + 1. In the case of of unsigned long, the value of ULONG_MAX certainly does not exceed pow(2,sizeof (unsigned long) * CHAR_BIT) - 1 so code could use:

#define LOG10_2 0.30102999566398119521373889472449 #define ULONG_STRING_SIZE (sizeof (unsigned long) * CHAR_BIT * LOG10_2 + 2) // For greater portability, should use integer math. #define ULONG_STRING_SIZE (sizeof (unsigned long) * CHAR_BIT / 3 + 2) // or more precisely #define ULONG_STRING_SIZE (sizeof (unsigned long) * CHAR_BIT * 28/93 + 2)

The short answer used +3 in case a signed` integer was specified.

Recommend

  • Increase height of tableview cell according to amount of UILabel text
  • golang: what does “%b” do in fmt.Printf for float64 and what is Min subnormal positive double in flo
  • Feeding gstreamer fdsrc via STDIN only produces fraction of expected result
  • Round up to nearest power of 10
  • Is there such a thing as static jar linking in java?
  • Jquery hide first 12 elementes, show next 12 elements
  • Using Double in Switch Statement
  • fscanf not reading floats correctly
  • OpenSSL::X509::Certificate Showing Certificate for Wrong Domain
  • Reaping zombie process - child
  • Initializing a class using malloc
  • Jooq casting String to BigDecimal
  • JSON data through JS/AJAX into PHP
  • Correctly Importing Apache Commons Math Package
  • Is it possible to use arbitrary image sizes in caffe?
  • Google Places API - Find a company's CID and LRD
  • Python cosine function precision [duplicate]
  • Calculate time difference in hh:mm:ss with simple javascript/jquery
  • C# fibonacci function returning errors
  • How do I display a dialog that asks the user multi-choice questıon using tkInter?
  • How to detect interior vertices in groups of 2d polygons? (E.g. ZIP Codes to determine a territory)
  • Convert Type Decimal to Hex (string) in .NET 3.5
  • D3 get axis values on zoom event
  • How to use carriage return with multiple line?
  • How do I open a C file with a relative path?
  • Use of this Javascript
  • Meteor helpers not available in Angular template
  • C++ Partial template specialization - design simplification
  • Linq Objects Group By & Sum
  • Is there a javascript serializer for JSON.Net?
  • Optimizing database types to compact database (SQLite)
  • Deserializing XML into class C#
  • Where to put my custom functions in Wordpress?
  • Why is the timeout on a windows udp receive socket always 500ms longer than set by SO_RCVTIMEO?
  • How to format a variable of double type
  • Transpose CSV data with awk (pivot transformation)
  • Hits per day in Google Big Query
  • How to get Windows thread pool to call class member function?
  • reshape alternating columns in less time and using less memory
  • Binding checkboxes to object values in AngularJs