Converting unsigned long to string in C

B

bmshivaraj

Hi,
Could any one tell me how to convert a unsigned long value into string
(char *) ?
In C++ there is a function _ultoa so wanted a similar one in C .
Regards,
Shivaraj
 
B

Ben Bacarisse

Could any one tell me how to convert a unsigned long value into string
(char *) ?

You want to look at snprintf with a format of "%lu". If you are not
lucky enough to have snprintf use sprintf with a large enough buffer.
 
S

santosh

Hi,
Could any one tell me how to convert a unsigned long value into string
(char *) ?
In C++ there is a function _ultoa so wanted a similar one in C .
Regards,
Shivaraj

sprintf and snprintf will do what you want.

<OT>

You probably want to use string streams in C++, rather than a primitive
like _ultoa.

</OT>
 
R

Richard Heathfield

(e-mail address removed) said:
Hi,
Could any one tell me how to convert a unsigned long value into string
(char *) ?

A char * isn't a string. It's just a way of pointing to one.
In C++ there is a function _ultoa so wanted a similar one in C .

C++ has no such function. It is almost certainly an extension provided by
your implementation.

First, make sure you have enough storage for the string representation of
the unsigned long value. In general, if there are CHAR_BIT bits in a byte
and sizeof(unsigned long) bytes in an unsigned long, then the largest
value that can be stored in an unsigned long will have a decimal
representation no longer than (CHAR_BIT * sizeof(unsigned long) + 2) / 3,
and you'll need a byte for the null terminating character, so we have:

#include <limits.h>
#include <stdio.h>

int main(void)
{
unsigned long n = 12345; /* whatever */
char s[(CHAR_BIT * sizeof n + 2) / 3 + 1];
sprintf(s, "%lu", n);
printf("The string value is [%s]\n", s);
return 0;
}
 
R

Richard

Richard Heathfield said:
(e-mail address removed) said:
Hi,
Could any one tell me how to convert a unsigned long value into string
(char *) ?

A char * isn't a string. It's just a way of pointing to one.
In C++ there is a function _ultoa so wanted a similar one in C .

C++ has no such function. It is almost certainly an extension provided by
your implementation.

First, make sure you have enough storage for the string representation of
the unsigned long value. In general, if there are CHAR_BIT bits in a byte
and sizeof(unsigned long) bytes in an unsigned long, then the largest
value that can be stored in an unsigned long will have a decimal
representation no longer than (CHAR_BIT * sizeof(unsigned long) + 2) / 3,
and you'll need a byte for the null terminating character, so we have:

#include <limits.h>
#include <stdio.h>

int main(void)
{
unsigned long n = 12345; /* whatever */
char s[(CHAR_BIT * sizeof n + 2) / 3 + 1];
sprintf(s, "%lu", n);
printf("The string value is [%s]\n", s);
return 0;
}

I hate this "fad" of using "sizeof n". It reads horribly.
 
S

Serve Laurijssen

Richard Heathfield said:
(e-mail address removed) said:
First, make sure you have enough storage for the string representation of
the unsigned long value. In general, if there are CHAR_BIT bits in a byte
and sizeof(unsigned long) bytes in an unsigned long, then the largest
value that can be stored in an unsigned long will have a decimal
representation no longer than (CHAR_BIT * sizeof(unsigned long) + 2) / 3,
and you'll need a byte for the null terminating character, so we have:

char s[(CHAR_BIT * sizeof n + 2) / 3 + 1];


I would do two things different. First its not immediately obvious where the
buffer size calculation comes from so I'd put that in a macro.
Second, if n becomes signed in the future you need one more space if n
becomes negative. The code gets a little easier to maintain then
 
R

Richard Tobin

Richard said:
I hate this "fad" of using "sizeof n". It reads horribly.

I agree. Since all other operators in C are symbols rather than
words, and function names are words rather than symbols, it's more
natural to treat sizeof as if it were a function.

And of course the operator-like form doesn't work for type names,
so it's more consistent to avoid it.

-- Richard
 
M

Martin Ambuhl

Hi,
Could any one tell me how to convert a unsigned long value into string
(char *) ?

sprintf and snprintf do that job quite nicely.
In C++ there is a function _ultoa so wanted a similar one in C .

You have been misled. There is no C++ function named _ultoa. Your
implementation may provide a non-standard, non-portable function with
that name, and if it does so for C++, it may do so for C. There are,
with less than a handful of exceptions, no standard functions in C or
C++ with names beginning with an underscore. If you see such an
identifier, be alert to the possibility that you are looking at a
completely non-standard, non-portable identifier, and even the next
edition of your implementation might not support it
 
K

Keith Thompson

I agree. Since all other operators in C are symbols rather than
words, and function names are words rather than symbols, it's more
natural to treat sizeof as if it were a function.

And of course the operator-like form doesn't work for type names,
so it's more consistent to avoid it.

I disagree. Since sizeof really is an operator, it makse sense to
treat it as one. Making it look like a function call is misleading.

Do you use extra parentheses on return statements?
 
R

Richard Tobin

I agree. Since all other operators in C are symbols rather than
words, and function names are words rather than symbols, it's more
natural to treat sizeof as if it were a function.

And of course the operator-like form doesn't work for type names,
so it's more consistent to avoid it.
[/QUOTE]
I disagree. Since sizeof really is an operator,

What exactly do you mean by this? In what sense is it "really an
operator"? It's a unique thing, with its own special syntax.
It doesn't work like either an operator or a function.
Making it look like a function call is misleading.

Making it look like an operator is "misleading" too; if it was an
operator you ought to be able to write "sizeof int". But anyway, what
do you mean, misleading? Who could it mislead?
Do you use extra parentheses on return statements?

"return" is a statement; it can't be used in an expression. There
isn't anything for it to be consistent with, and there aren't two
different syntaxes depending on its operand.

-- Richard
 
E

Eric Sosman

Richard said:
What exactly do you mean by this? In what sense is it "really an
operator"? It's a unique thing, with its own special syntax.
It doesn't work like either an operator or a function.

The sense in which it "really is an operator" is the
sense in which the Standard uses the term "operator." For
example,

6.5.3.4 The sizeof operator
Constraints
1) The sizeof operator shall not be applied to [...]
Semantics
2) The sizeof operator yields the size [...]
 
J

J. J. Farrell

I disagree. Since sizeof really is an operator,

What exactly do you mean by this? In what sense is it "really an
operator"?[/QUOTE]

Presumably in the sense that it is an operator.
It's a unique thing, with its own special syntax.
It doesn't work like either an operator or a function.

It's an operator, just like any other operator except for an extension
which allows it to operate on parenthesized type names.
... if it was an
operator you ought to be able to write "sizeof int".

Why? To be consistent with 'a *= int' and '47 + int'? As far as I
recall, sizeof is the only operator which can operate on type names.
There's a rule that type names have to be in parenthesis when being
operated on. I expect that if any other operator gets added which can
operate on type names, the same rule will apply.
 
R

Richard Tobin

What exactly do you mean by this? In what sense is it "really an
operator"? It's a unique thing, with its own special syntax.
It doesn't work like either an operator or a function.
[/QUOTE]
The sense in which it "really is an operator" is the
sense in which the Standard uses the term "operator."

Which is not relevant to whether it's more or less confusing to write
it without parentheses.

-- Richard
 
M

Mark McIntyre

I disagree. Since sizeof really is an operator,

What exactly do you mean by this? In what sense is it "really an
operator"? [/QUOTE]

In the sense that it actually is an operator, as defined by the standard
 
M

Mark McIntyre

The sense in which it "really is an operator" is the
sense in which the Standard uses the term "operator."

Which is not relevant to whether it's more or less confusing to write
it without parentheses.[/QUOTE]

So what?
Your question above was "in what sense is it really an operator?". The
answer is that it is defined as such.
 
B

Ben Bacarisse

pete said:
Richard said:
unsigned long n = 12345; /* whatever */
char s[(CHAR_BIT * sizeof n + 2) / 3 + 1];

Where are you getting "+ 2" from?

I image it is habit from the general case.

Here is low-down in case anyone is interested. It would be nice if
n_bits/3 were enough for the decimal representation of an unsigned
integer n_bits wide, but it is not. Interestingly is *is* enough for
C's unsigned long, since the longest integers for which this
expression fails to be large enough is 20 bits -- and C guarantees
more than 20 bits for unsigned long.

There are three bit sizes at which the more generous (n_bits + 1)/3 is
not enough: 1, 4, 7 and 10. The minimum range guaranteed for C's
unsigned int means that (CHAR_BIT * sizeof n + 1)/3 is enough for that
type, but not for unsigned char if CHAR_BIT is 10.

The upshot is that if the type not constrained, you need to add 2 and
divide by three and I imagine many people just remember this as rule
of thumb (I did until a few minutes ago!).

Obviously, add one for a sign bit and one for null as required.
 
E

Eric Sosman

pete said:
Richard said:
unsigned long n = 12345; /* whatever */
char s[(CHAR_BIT * sizeof n + 2) / 3 + 1];

Where are you getting "+ 2" from?

3 - 1

;-)

Familiar trick: To divide integers M / N and get the
ceiling ("round up") instead of floor ("truncate"), divide
(M + N - 1) / N instead. Work it out for yourself; choose
a value like N==3 and go through the possibilities.
 
K

Keith Thompson

What exactly do you mean by this? In what sense is it "really an
operator"? It's a unique thing, with its own special syntax.
It doesn't work like either an operator or a function.

As several others have pointed out, the standard refers to it as the
"sizeof operator"; it doesn't call it a "unary-operator", though it
does describe it in the section on "Unary operators" (C99 6.5.3).
Note that prefix "++" and "--" are described in the same section;
they're also referred to as operators, but are not considered
"unary-operators" either.

It happens to be the only operator in the language whose name is a
keyword rather than a token composed of one or more punctuation
symbols, but it's no less an operator because of that. (It's also
nearly unique in that it doesn't evaluate its operand -- unless, of
course the operand is a VLA (but it's not quite that simple).) I'll
grant you that its uniqueness can cause some confusion, but I find
that it really is easier to think of it as an operator (which implies
that the parentheses in "sizeof(x)" are unnecessary).

And, of course, the fact that the grammar explicitly allows
"sizeof x", where "x" is an expression, reinforces the point.

Note that some languages have a number of operators that use keywords
(For example, Ada has "and", "or", "xor", "not", "mod", "rem", "abs",
"not", even though the fundamental arithmetic operators use the usual
symbols "+", "-", "/", "*".)

There are actually two distinct forms of "sizeof". One of
them is a unary operator whose operand is a "unary-expression".
The other has the syntax "sizeof ( type-name )". I would not have
chosen to call the "sizeof" in the latter an operator; rather,
I would prefer to limit the term "operator" to something that
takes one or more "operands" which are themselves expressions,
and treat "sizeof ( type-name )" as a separate class of expression.
But that's the terminology the authors of the standard chose to use.
Making it look like an operator is "misleading" too; if it was an
operator you ought to be able to write "sizeof int".

Oh? Can you write "- int"?
But anyway, what
do you mean, misleading? Who could it mislead?

I didn't have any particular potential victim in mind. But I dislike
making something look like a function call (or a macro invocation)
when it really isn't.
"return" is a statement; it can't be used in an expression. There
isn't anything for it to be consistent with, and there aren't two
different syntaxes depending on its operand.

"sizeof(x)" looks like a function call, though it isn't.
"return(x)" looks like a function call, though it isn't.
In both cases, in my opinion, that's enough reason not to use
the parentheses.

Of course you should use parentheses if the argument is sufficiently
complex that it's ambiguous, either to the compiler or to a human
reader. There are no such cases for return; there probably are
such cases for sizeof. But in the normal case, I prefer not to
use extraneous parentheses in a sizeof expression other than the
"sizeof ( type-name )" form.
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top