convert string to size_t

R

rtillmore

Hi,

There is a nice function called atoi that converts strings to ints.
Is there a way to convert a string to size_t?

Thanks,
 
P

Peter Nilsson

Hi,

There is a nice function called atoi that converts
strings to ints.

Better is strtol().
Is there a way to convert a string to size_t?

There is strtol and strtoul in C90, and additionally
strtoimax and strtoumax in C99. It's often better
to use the signed conversions since the unsigned
conversion don't capture errors in values that would
be outside the range of the result unsigned type.
 
M

Martien Verbruggen

In practise strtod() followed by a cast to size_t is going to be good
enough. doubles can usually represent enough integers to index the biggest
array.

However if you want to be really portable, you'll have to roll your own.
It's not too difficult. The standard even has a special and unenforceable
requirement that digits be represented contigously from 0-9 in order to aid
your task.

What do you mean 'special and unenforceable'? What is there to be
enforced?

A C implementation is only a C implementation if 0-9 are contiguous. If
they are not, it's not a C implementation.

Martien
 
R

rtillmore

Better is strtol().


There is strtol and strtoul in C90, and additionally
strtoimax and strtoumax in C99. It's often better
to use the signed conversions since the unsigned
conversion don't capture errors in values that would
be outside the range of the result unsigned type.

Thanks for the information. My data will never be less
than zero so unsigned is good enough.
 
B

Ben Bacarisse

It is best not to quote sigs.
Thanks for the information. My data will never be less
than zero so unsigned is good enough.

OK, but I worry that you may not have picked up on Peter Nilsson's
warning. Your (valid) data may never be less that zero, but you can't
easily check that this is the case using the unsigned strtou*
functions. For example, strtoul("-1", NULL, 0) returns ULONG_MAX
without any indication of an error. strtol will return -1 so you can
report an invalid input.

If by "my data will never be less than zero" you meant that you don't
need to check for negative data, then all is well, but I thought it
worth checking.
 
K

Keith Thompson

It's not a "nice" function at all. It does no error checking, and can
actually invoke undefined behavior for some inputs.
In practise strtod() followed by a cast to size_t is going to be good
enough. doubles can usually represent enough integers to index the
biggest array.

Why would you advise going through a floating-point type when it's not
necessary? strtoul or strtoull (the latter is C99-specific) should be
perfectly adequate.

[...]
 
M

Martin Ambuhl

Malcolm said:
In practise strtod() followed by a cast to size_t is going to be good
enough. doubles can usually represent enough integers to index the
biggest array.

Actually, strtoumax() is a much better choice, and so is strtoull().

Your suggestion
strtod() returns a double, which is almost certainly a bad idea.
strtof() and strtold() are poor because they similarly return floating
point values (float & long double)/

strtol(), strtoll(), and strtoimax() return signed values (so may be
insufficient) since size_t is an unsigned value.

strtoul() returns an unsigned long, which may not be sufficient.

strtoull() returning an unsigned long long will almost certainly do the
jog, but to be as sure as possible use strtoumax() which returns an
uintmax_t. strtoumax() requires <inttypes.h>. If you don't have this
header or if the type uintmax_t is missing from it, or if strtoumax() is
missing, relying on strtoull() is probably sufficient.
However if you want to be really portable, you'll have to roll your own.

For damn sure if you think strtod() is the way to go.
It's not too difficult. The standard even has a special and
unenforceable requirement that digits be represented contigously from
0-9 in order to aid your task.

It's easily enforceable. If the digits o-9 do not have continuous and
increasing representations, then you don't have a C compiler.
 
A

Andrey Tarasevich

Ben said:
OK, but I worry that you may not have picked up on Peter Nilsson's
warning. Your (valid) data may never be less that zero, but you can't
easily check that this is the case using the unsigned strtou*
functions. For example, strtoul("-1", NULL, 0) returns ULONG_MAX
without any indication of an error. strtol will return -1 so you can
report an invalid input.

Isn't 'strtoul' also supposed to report a range error through 'errno' in
this case?
 
B

Ben Bacarisse

Andrey Tarasevich said:
Isn't 'strtoul' also supposed to report a range error through 'errno'
in this case?

Not as far as I can see and at least one implementation does not do
this. I am working from a draft of C99, but C90 seems to have similar
text.
 
C

CBFalconer

There is a nice function called atoi that converts strings to ints.
Is there a way to convert a string to size_t?

Ignore atoi. It doesn't catch errors. Look up the various
strto...() functions available.
 
P

Peter Nilsson

Andrey Tarasevich said:
Isn't 'strtoul' also supposed to report a range error
through 'errno' in this case?

Unfortunately (IMHO), all the strtoxxx functions take an
input sequence with an optional plus or minus sign. The
behaviour on minus is '...the value resulting from
the conversion is negated (in the return type).'

Thus, there is only a range error if the digits of the
subject sequence are outside of the range of the
unsigned type. Just as -1u is actually the negation of
an unsigned int value, so "-1" will yield the negation
of the unsigned integer 1 in the unsigned strtoxxx
functions.
 

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,774
Messages
2,569,598
Members
45,151
Latest member
JaclynMarl
Top