How to convert a string to integer in C?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I am trying to find out if there is an alternative way of converting string to integer in C.
I regularly pattern the following in my code.
char s = "45";
int num = atoi(s);
So, is there a better way or another way?
c string atoi
|
show 1 more comment
I am trying to find out if there is an alternative way of converting string to integer in C.
I regularly pattern the following in my code.
char s = "45";
int num = atoi(s);
So, is there a better way or another way?
c string atoi
20
Your tags and title say you want a solution in C, but your question says C or C++. Which one do you want?
– In silico
Aug 11 '11 at 6:32
1
@Yann, Sorry for that confusion. I will prefer C .
– user618677
Aug 11 '11 at 16:16
1
It works, but it's not the recommended way, because there is no way to handle errors. Never use this in production code unless you can trust the input 100%.
– Uwe Geuder
Nov 5 '15 at 17:47
1
Define 'better', and state clearly why you need another way.
– user207421
Jun 18 '18 at 10:35
1
@EJP Just to improve myself.
– user618677
Aug 3 '18 at 1:32
|
show 1 more comment
I am trying to find out if there is an alternative way of converting string to integer in C.
I regularly pattern the following in my code.
char s = "45";
int num = atoi(s);
So, is there a better way or another way?
c string atoi
I am trying to find out if there is an alternative way of converting string to integer in C.
I regularly pattern the following in my code.
char s = "45";
int num = atoi(s);
So, is there a better way or another way?
c string atoi
c string atoi
edited May 1 '18 at 13:10
Rodrigo de Azevedo
780517
780517
asked Aug 11 '11 at 6:30
user618677user618677
1,76551721
1,76551721
20
Your tags and title say you want a solution in C, but your question says C or C++. Which one do you want?
– In silico
Aug 11 '11 at 6:32
1
@Yann, Sorry for that confusion. I will prefer C .
– user618677
Aug 11 '11 at 16:16
1
It works, but it's not the recommended way, because there is no way to handle errors. Never use this in production code unless you can trust the input 100%.
– Uwe Geuder
Nov 5 '15 at 17:47
1
Define 'better', and state clearly why you need another way.
– user207421
Jun 18 '18 at 10:35
1
@EJP Just to improve myself.
– user618677
Aug 3 '18 at 1:32
|
show 1 more comment
20
Your tags and title say you want a solution in C, but your question says C or C++. Which one do you want?
– In silico
Aug 11 '11 at 6:32
1
@Yann, Sorry for that confusion. I will prefer C .
– user618677
Aug 11 '11 at 16:16
1
It works, but it's not the recommended way, because there is no way to handle errors. Never use this in production code unless you can trust the input 100%.
– Uwe Geuder
Nov 5 '15 at 17:47
1
Define 'better', and state clearly why you need another way.
– user207421
Jun 18 '18 at 10:35
1
@EJP Just to improve myself.
– user618677
Aug 3 '18 at 1:32
20
20
Your tags and title say you want a solution in C, but your question says C or C++. Which one do you want?
– In silico
Aug 11 '11 at 6:32
Your tags and title say you want a solution in C, but your question says C or C++. Which one do you want?
– In silico
Aug 11 '11 at 6:32
1
1
@Yann, Sorry for that confusion. I will prefer C .
– user618677
Aug 11 '11 at 16:16
@Yann, Sorry for that confusion. I will prefer C .
– user618677
Aug 11 '11 at 16:16
1
1
It works, but it's not the recommended way, because there is no way to handle errors. Never use this in production code unless you can trust the input 100%.
– Uwe Geuder
Nov 5 '15 at 17:47
It works, but it's not the recommended way, because there is no way to handle errors. Never use this in production code unless you can trust the input 100%.
– Uwe Geuder
Nov 5 '15 at 17:47
1
1
Define 'better', and state clearly why you need another way.
– user207421
Jun 18 '18 at 10:35
Define 'better', and state clearly why you need another way.
– user207421
Jun 18 '18 at 10:35
1
1
@EJP Just to improve myself.
– user618677
Aug 3 '18 at 1:32
@EJP Just to improve myself.
– user618677
Aug 3 '18 at 1:32
|
show 1 more comment
11 Answers
11
active
oldest
votes
There is strtol
which is better IMO. Also I have taken a liking in strtonum
, so use it if you have it (but remember it's not portable):
long long
strtonum(const char *nptr, long long minval, long long maxval,
const char **errstr);
EDIT
You might also be interested in strtoumax
and strtoimax
which are standard functions in C99. For example you could say:
uintmax_t num = strtoumax(s, NULL, 10);
if (num == UINTMAX_MAX && errno == ERANGE)
/* Could not convert. */
Anyway, stay away from atoi
:
The call atoi(str) shall be equivalent to:
(int) strtol(str, (char **)NULL, 10)
except that the handling of errors may differ. If the value cannot be
represented, the behavior is undefined.
what do I need to include forstrtonum
? I keep getting an implicit declaration warning
– jsj
Mar 30 '13 at 1:57
@trideceth12 On systems where it's available it should be declared in#<stdlib.h>
. However, you could use the standardstrtoumax
alternative.
– cnicutar
Mar 30 '13 at 10:21
3
This answer doesn't seem shorter than the questioner's first code.
– Azurespot
Sep 3 '14 at 4:46
10
@NoniA. Conciseness is always good, but not at the expense of correctness.
– cnicutar
Sep 3 '14 at 9:33
5
Not so much wrong as unsafe. atoi() works if input is valid. But what if you do atoi("cat")? strtol() has defined behavior if the value cannot be represented as a long, atoi() does not.
– Daniel B.
Jul 22 '15 at 19:13
|
show 2 more comments
Robust C89 strtol
-based solution
With:
- no undefined behavior (as could be had with the
atoi
family) - a stricter definition of integer than
strtol
(e.g. no leading whitespace nor trailing trash chars) - classification of the error case (e.g. to give useful error messages to users)
- a "testsuite"
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
typedef enum {
STR2INT_SUCCESS,
STR2INT_OVERFLOW,
STR2INT_UNDERFLOW,
STR2INT_INCONVERTIBLE
} str2int_errno;
/* Convert string s to int out.
*
* @param[out] out The converted int. Cannot be NULL.
*
* @param[in] s Input string to be converted.
*
* The format is the same as strtol,
* except that the following are inconvertible:
*
* - empty string
* - leading whitespace
* - any trailing characters that are not part of the number
*
* Cannot be NULL.
*
* @param[in] base Base to interpret string in. Same range as strtol (2 to 36).
*
* @return Indicates if the operation succeeded, or why it failed.
*/
str2int_errno str2int(int *out, char *s, int base) {
char *end;
if (s[0] == '' || isspace(s[0]))
return STR2INT_INCONVERTIBLE;
errno = 0;
long l = strtol(s, &end, base);
/* Both checks are needed because INT_MAX == LONG_MAX is possible. */
if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
return STR2INT_OVERFLOW;
if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
return STR2INT_UNDERFLOW;
if (*end != '')
return STR2INT_INCONVERTIBLE;
*out = l;
return STR2INT_SUCCESS;
}
int main(void) {
int i;
/* Lazy to calculate this size properly. */
char s[256];
/* Simple case. */
assert(str2int(&i, "11", 10) == STR2INT_SUCCESS);
assert(i == 11);
/* Negative number . */
assert(str2int(&i, "-11", 10) == STR2INT_SUCCESS);
assert(i == -11);
/* Different base. */
assert(str2int(&i, "11", 16) == STR2INT_SUCCESS);
assert(i == 17);
/* 0 */
assert(str2int(&i, "0", 10) == STR2INT_SUCCESS);
assert(i == 0);
/* INT_MAX. */
sprintf(s, "%d", INT_MAX);
assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
assert(i == INT_MAX);
/* INT_MIN. */
sprintf(s, "%d", INT_MIN);
assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
assert(i == INT_MIN);
/* Leading and trailing space. */
assert(str2int(&i, " 1", 10) == STR2INT_INCONVERTIBLE);
assert(str2int(&i, "1 ", 10) == STR2INT_INCONVERTIBLE);
/* Trash characters. */
assert(str2int(&i, "a10", 10) == STR2INT_INCONVERTIBLE);
assert(str2int(&i, "10a", 10) == STR2INT_INCONVERTIBLE);
/* int overflow.
*
* `if` needed to avoid undefined behaviour
* on `INT_MAX + 1` if INT_MAX == LONG_MAX.
*/
if (INT_MAX < LONG_MAX) {
sprintf(s, "%ld", (long int)INT_MAX + 1L);
assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
}
/* int underflow */
if (LONG_MIN < INT_MIN) {
sprintf(s, "%ld", (long int)INT_MIN - 1L);
assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
}
/* long overflow */
sprintf(s, "%ld0", LONG_MAX);
assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
/* long underflow */
sprintf(s, "%ld0", LONG_MIN);
assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
return EXIT_SUCCESS;
}
GitHub upstream.
Based on: https://stackoverflow.com/a/6154614/895245
3
Nice robuststr2int()
. Pedantic: useisspace((unsigned char) s[0])
.
– chux
May 30 '16 at 12:09
@chux thanks! Can you explain a bit more why the(unsigned char)
cast could make a difference?
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:00
1
@chux thanks! OMG, C is so hard :-) greenend.org.uk/rjk/tech/cfu.html
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:51
IAR C compiler warns thatl > INT_MAX
andl < INT_MIN
are pointless integer comparison since either result is always false. What happens if I change them tol >= INT_MAX
andl <= INT_MIN
to clear the warnings? On ARM C, long and int are 32-bit signed Basic data types in ARM C and C++
– ecle
Jan 26 '17 at 2:23
@ecle changing code tol >= INT_MAX
incurs incorrect functionality: Example returningSTR2INT_OVERFLOW
with input"32767"
and 16-bitint
. Use a conditional compile. Example.
– chux
Dec 20 '17 at 12:45
|
show 3 more comments
Don't use functions from ato...
group. These are broken and virtually useless. A moderately better solution would be to use sscanf
, although it is not perfect either.
To convert string to integer, functions from strto...
group should be used. In your specific case it would be strtol
function.
7
sscanf
actually has undefined behavior if it tries to convert a number outside the range of its type (for example,sscanf("999999999999999999999", "%d", &n)
).
– Keith Thompson
Aug 11 '11 at 6:50
1
@Keith Thompson: That's exactly what I mean.atoi
provides no meaningful success/failure feedback and has undefined behavior on overflow.sscanf
provides success/failure feedback of sorts (the return value, which is what makes it "moderately better"), but still has undefined behavior on overflow. Onlystrtol
is a viable solution.
– AnT
Aug 11 '11 at 6:55
1
Agreed; I just wanted to emphasize the potentially fatal problem withsscanf
. (Though I confess I sometimes useatoi
, usually for programs that I don't expect to survive more than 10 minute before I delete the source.)
– Keith Thompson
Aug 11 '11 at 6:58
add a comment |
You can code a little atoi() for fun:
int my_getnbr(char *str)
{
int result;
int puiss;
result = 0;
puiss = 1;
while (('-' == (*str)) || ((*str) == '+'))
{
if (*str == '-')
puiss = puiss * -1;
str++;
}
while ((*str >= '0') && (*str <= '9'))
{
result = (result * 10) + ((*str) - '0');
str++;
}
return (result * puiss);
}
You can also make it recursive wich can old in 3 lines =)
Thanks so much .. But could you tell me how the below code works?code
((*str) - '0')code
– user618677
Aug 11 '11 at 16:15
a character has an ascii value. If you are uner linux type: man ascii in the shell or if not go to:table-ascii.com. You will see that the character '0' = 68 (i think) for a int. So to get the number of '9' (it's '0' + 9) so you get 9 = '9' - '0'. You get it?
– jDourlens
Aug 11 '11 at 16:31
1
1) The code allows"----1"
2) Has undefined behavior withint
overflow when the result should beINT_MIN
. Considermy_getnbr("-2147483648")
– chux
May 30 '16 at 12:12
Thanks for precision, it was just for showing a little example. As it's said it for fun and learning. You should definetly use standart lib for this kind of tasks. Faster and safer!
– jDourlens
Jun 1 '16 at 0:12
add a comment |
Just wanted to share a solution for unsigned long aswell.
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
1
Doesn't handle overflow. Also, the parameter should beconst char *
.
– Roland Illig
Jan 21 '17 at 17:35
1
Plus, what's that48
mean? Are you assuming that's the value of'0'
where the code will run? Please don't inflict such broad assumptions on the world!
– Toby Speight
Jun 18 '18 at 16:15
@TobySpeight Yes I assume 48 represent '0' in the ascii table.
– Jacob
Jun 20 '18 at 9:17
1
Not all the world is ASCII - just use'0'
like you should.
– Toby Speight
Jun 20 '18 at 10:42
add a comment |
This function will help you
int strtoint_n(char* str, int n)
{
int sign = 1;
int place = 1;
int ret = 0;
int i;
for (i = n-1; i >= 0; i--, place *= 10)
{
int c = str[i];
switch (c)
{
case '-':
if (i == 0) sign = -1;
else return -1;
break;
default:
if (c >= '0' && c <= '9') ret += (c - '0') * place;
else return -1;
}
}
return sign * ret;
}
int strtoint(char* str)
{
char* temp = str;
int n = 0;
while (*temp != '')
{
n++;
temp++;
}
return strtoint_n(str, n);
}
Ref: http://amscata.blogspot.com/2013/09/strnumstr-version-2.html
1
Why do this though? One of the biggest problems withatoi
and friends is that if there's overflow, it's undefined behavior. Your function does not check for this.strtol
and friends do.
– chad
Sep 2 '15 at 19:45
1
Yup. Since C is not Python I hope that the people who use C language are aware of these kind of overflow errors. Everything has it's own limits.
– Amith Chinthaka
Sep 3 '15 at 9:04
add a comment |
Ok, I had the same problem.I came up with this solution.It worked for me the best.I did try atoi() but didn't work well for me.So here is my solution:
void splitInput(int arr, int sizeArr, char num)
{
for(int i = 0; i < sizeArr; i++)
// We are subtracting 48 because the numbers in ASCII starts at 48.
arr[i] = (int)num[i] - 48;
}
add a comment |
//I think this way we could go :
int my_atoi(const char* snum)
{
int nInt(0);
int index(0);
while(snum[index])
{
if(!nInt)
nInt= ( (int) snum[index]) - 48;
else
{
nInt = (nInt *= 10) + ((int) snum[index] - 48);
}
index++;
}
return(nInt);
}
int main()
{
printf("Returned number is: %dn", my_atoi("676987"));
return 0;
}
Code does not compile in C. WhynInt = (nInt *= 10) + ((int) snum[index] - 48);
vs.nInt = nInt*10 + snum[index] - '0';
if(!nInt)
not needed.
– chux
May 30 '16 at 12:19
add a comment |
You can always roll your own!
#include <stdio.h>
#include <string.h>
#include <math.h>
int my_atoi(const char* snum)
{
int idx, strIdx = 0, accum = 0, numIsNeg = 0;
const unsigned int NUMLEN = (int)strlen(snum);
/* Check if negative number and flag it. */
if(snum[0] == 0x2d)
numIsNeg = 1;
for(idx = NUMLEN - 1; idx >= 0; idx--)
{
/* Only process numbers from 0 through 9. */
if(snum[strIdx] >= 0x30 && snum[strIdx] <= 0x39)
accum += (snum[strIdx] - 0x30) * pow(10, idx);
strIdx++;
}
/* Check flag to see if originally passed -ve number and convert result if so. */
if(!numIsNeg)
return accum;
else
return accum * -1;
}
int main()
{
/* Tests... */
printf("Returned number is: %dn", my_atoi("34574"));
printf("Returned number is: %dn", my_atoi("-23"));
return 0;
}
This will do what you want without clutter.
2
But... why? This doesn't check for overflow and simply ignores garbage values. There's no reason not to use thestrto...
family of functions. They are portable and significantly better.
– chad
Sep 2 '15 at 19:41
1
Strange to use0x2d, 0x30
instead of'-', '0'
. Does not allow'+'
sign. Why(int)
cast in(int)strlen(snum)
? UB if input is""
. UB when result isINT_MIN
due toint
overflow withaccum += (snum[strIdx] - 0x30) * pow(10, idx);
– chux
May 30 '16 at 12:24
@chux - This code is demonstration code. There are easy fixes to what you described as potential issues.
– ButchDean
Jun 7 '16 at 4:12
1
@ButchDean What you describe as "demonstration code" will be used by others who have no clue about all the details. Only the negative score and the comments on this answer protect them now. In my opinion, "demonstration code" must have much higher quality.
– Roland Illig
Jan 21 '17 at 17:39
@RolandIllig Rather than being all critical, wouldn't it be more helpful to others to actually put up your own solution?
– ButchDean
Jan 24 '17 at 17:35
|
show 6 more comments
In C++, you can use a such function:
template <typename T>
T to(const std::string & s)
{
std::istringstream stm(s);
T result;
stm >> result;
if(stm.tellg() != s.size())
throw error;
return result;
}
This can help you to convert any string to any type such as float, int, double...
1
There's already a similar question covering C++, where the problems with this approach are explained.
– Ben Voigt
Feb 20 '15 at 17:28
add a comment |
Yes, you can store the integer directly:
int num = 45;
If you must parse a string, atoi
or strol
is going to win the "shortest amount of code" contest.
If you want to do it safely,strtol()
actually requires a fair amount of code. It can returnLONG_MIN
orLONG_MAX
either if that's the actual converted value or if there's an underflow or overflow, and it can return 0 either if that's the actual value or if there was no number to convert. You need to seterrno = 0
before the call, and check theendptr
.
– Keith Thompson
Aug 11 '11 at 6:54
The solutions given to parse, are no viable solutions.
– BananaAcid
Feb 1 '18 at 21:15
add a comment |
protected by Mysticial Mar 15 '14 at 21:52
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
11 Answers
11
active
oldest
votes
11 Answers
11
active
oldest
votes
active
oldest
votes
active
oldest
votes
There is strtol
which is better IMO. Also I have taken a liking in strtonum
, so use it if you have it (but remember it's not portable):
long long
strtonum(const char *nptr, long long minval, long long maxval,
const char **errstr);
EDIT
You might also be interested in strtoumax
and strtoimax
which are standard functions in C99. For example you could say:
uintmax_t num = strtoumax(s, NULL, 10);
if (num == UINTMAX_MAX && errno == ERANGE)
/* Could not convert. */
Anyway, stay away from atoi
:
The call atoi(str) shall be equivalent to:
(int) strtol(str, (char **)NULL, 10)
except that the handling of errors may differ. If the value cannot be
represented, the behavior is undefined.
what do I need to include forstrtonum
? I keep getting an implicit declaration warning
– jsj
Mar 30 '13 at 1:57
@trideceth12 On systems where it's available it should be declared in#<stdlib.h>
. However, you could use the standardstrtoumax
alternative.
– cnicutar
Mar 30 '13 at 10:21
3
This answer doesn't seem shorter than the questioner's first code.
– Azurespot
Sep 3 '14 at 4:46
10
@NoniA. Conciseness is always good, but not at the expense of correctness.
– cnicutar
Sep 3 '14 at 9:33
5
Not so much wrong as unsafe. atoi() works if input is valid. But what if you do atoi("cat")? strtol() has defined behavior if the value cannot be represented as a long, atoi() does not.
– Daniel B.
Jul 22 '15 at 19:13
|
show 2 more comments
There is strtol
which is better IMO. Also I have taken a liking in strtonum
, so use it if you have it (but remember it's not portable):
long long
strtonum(const char *nptr, long long minval, long long maxval,
const char **errstr);
EDIT
You might also be interested in strtoumax
and strtoimax
which are standard functions in C99. For example you could say:
uintmax_t num = strtoumax(s, NULL, 10);
if (num == UINTMAX_MAX && errno == ERANGE)
/* Could not convert. */
Anyway, stay away from atoi
:
The call atoi(str) shall be equivalent to:
(int) strtol(str, (char **)NULL, 10)
except that the handling of errors may differ. If the value cannot be
represented, the behavior is undefined.
what do I need to include forstrtonum
? I keep getting an implicit declaration warning
– jsj
Mar 30 '13 at 1:57
@trideceth12 On systems where it's available it should be declared in#<stdlib.h>
. However, you could use the standardstrtoumax
alternative.
– cnicutar
Mar 30 '13 at 10:21
3
This answer doesn't seem shorter than the questioner's first code.
– Azurespot
Sep 3 '14 at 4:46
10
@NoniA. Conciseness is always good, but not at the expense of correctness.
– cnicutar
Sep 3 '14 at 9:33
5
Not so much wrong as unsafe. atoi() works if input is valid. But what if you do atoi("cat")? strtol() has defined behavior if the value cannot be represented as a long, atoi() does not.
– Daniel B.
Jul 22 '15 at 19:13
|
show 2 more comments
There is strtol
which is better IMO. Also I have taken a liking in strtonum
, so use it if you have it (but remember it's not portable):
long long
strtonum(const char *nptr, long long minval, long long maxval,
const char **errstr);
EDIT
You might also be interested in strtoumax
and strtoimax
which are standard functions in C99. For example you could say:
uintmax_t num = strtoumax(s, NULL, 10);
if (num == UINTMAX_MAX && errno == ERANGE)
/* Could not convert. */
Anyway, stay away from atoi
:
The call atoi(str) shall be equivalent to:
(int) strtol(str, (char **)NULL, 10)
except that the handling of errors may differ. If the value cannot be
represented, the behavior is undefined.
There is strtol
which is better IMO. Also I have taken a liking in strtonum
, so use it if you have it (but remember it's not portable):
long long
strtonum(const char *nptr, long long minval, long long maxval,
const char **errstr);
EDIT
You might also be interested in strtoumax
and strtoimax
which are standard functions in C99. For example you could say:
uintmax_t num = strtoumax(s, NULL, 10);
if (num == UINTMAX_MAX && errno == ERANGE)
/* Could not convert. */
Anyway, stay away from atoi
:
The call atoi(str) shall be equivalent to:
(int) strtol(str, (char **)NULL, 10)
except that the handling of errors may differ. If the value cannot be
represented, the behavior is undefined.
edited Oct 11 '15 at 8:11
Spikatrix
17.7k62762
17.7k62762
answered Aug 11 '11 at 6:32
cnicutarcnicutar
147k19276329
147k19276329
what do I need to include forstrtonum
? I keep getting an implicit declaration warning
– jsj
Mar 30 '13 at 1:57
@trideceth12 On systems where it's available it should be declared in#<stdlib.h>
. However, you could use the standardstrtoumax
alternative.
– cnicutar
Mar 30 '13 at 10:21
3
This answer doesn't seem shorter than the questioner's first code.
– Azurespot
Sep 3 '14 at 4:46
10
@NoniA. Conciseness is always good, but not at the expense of correctness.
– cnicutar
Sep 3 '14 at 9:33
5
Not so much wrong as unsafe. atoi() works if input is valid. But what if you do atoi("cat")? strtol() has defined behavior if the value cannot be represented as a long, atoi() does not.
– Daniel B.
Jul 22 '15 at 19:13
|
show 2 more comments
what do I need to include forstrtonum
? I keep getting an implicit declaration warning
– jsj
Mar 30 '13 at 1:57
@trideceth12 On systems where it's available it should be declared in#<stdlib.h>
. However, you could use the standardstrtoumax
alternative.
– cnicutar
Mar 30 '13 at 10:21
3
This answer doesn't seem shorter than the questioner's first code.
– Azurespot
Sep 3 '14 at 4:46
10
@NoniA. Conciseness is always good, but not at the expense of correctness.
– cnicutar
Sep 3 '14 at 9:33
5
Not so much wrong as unsafe. atoi() works if input is valid. But what if you do atoi("cat")? strtol() has defined behavior if the value cannot be represented as a long, atoi() does not.
– Daniel B.
Jul 22 '15 at 19:13
what do I need to include for
strtonum
? I keep getting an implicit declaration warning– jsj
Mar 30 '13 at 1:57
what do I need to include for
strtonum
? I keep getting an implicit declaration warning– jsj
Mar 30 '13 at 1:57
@trideceth12 On systems where it's available it should be declared in
#<stdlib.h>
. However, you could use the standard strtoumax
alternative.– cnicutar
Mar 30 '13 at 10:21
@trideceth12 On systems where it's available it should be declared in
#<stdlib.h>
. However, you could use the standard strtoumax
alternative.– cnicutar
Mar 30 '13 at 10:21
3
3
This answer doesn't seem shorter than the questioner's first code.
– Azurespot
Sep 3 '14 at 4:46
This answer doesn't seem shorter than the questioner's first code.
– Azurespot
Sep 3 '14 at 4:46
10
10
@NoniA. Conciseness is always good, but not at the expense of correctness.
– cnicutar
Sep 3 '14 at 9:33
@NoniA. Conciseness is always good, but not at the expense of correctness.
– cnicutar
Sep 3 '14 at 9:33
5
5
Not so much wrong as unsafe. atoi() works if input is valid. But what if you do atoi("cat")? strtol() has defined behavior if the value cannot be represented as a long, atoi() does not.
– Daniel B.
Jul 22 '15 at 19:13
Not so much wrong as unsafe. atoi() works if input is valid. But what if you do atoi("cat")? strtol() has defined behavior if the value cannot be represented as a long, atoi() does not.
– Daniel B.
Jul 22 '15 at 19:13
|
show 2 more comments
Robust C89 strtol
-based solution
With:
- no undefined behavior (as could be had with the
atoi
family) - a stricter definition of integer than
strtol
(e.g. no leading whitespace nor trailing trash chars) - classification of the error case (e.g. to give useful error messages to users)
- a "testsuite"
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
typedef enum {
STR2INT_SUCCESS,
STR2INT_OVERFLOW,
STR2INT_UNDERFLOW,
STR2INT_INCONVERTIBLE
} str2int_errno;
/* Convert string s to int out.
*
* @param[out] out The converted int. Cannot be NULL.
*
* @param[in] s Input string to be converted.
*
* The format is the same as strtol,
* except that the following are inconvertible:
*
* - empty string
* - leading whitespace
* - any trailing characters that are not part of the number
*
* Cannot be NULL.
*
* @param[in] base Base to interpret string in. Same range as strtol (2 to 36).
*
* @return Indicates if the operation succeeded, or why it failed.
*/
str2int_errno str2int(int *out, char *s, int base) {
char *end;
if (s[0] == '' || isspace(s[0]))
return STR2INT_INCONVERTIBLE;
errno = 0;
long l = strtol(s, &end, base);
/* Both checks are needed because INT_MAX == LONG_MAX is possible. */
if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
return STR2INT_OVERFLOW;
if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
return STR2INT_UNDERFLOW;
if (*end != '')
return STR2INT_INCONVERTIBLE;
*out = l;
return STR2INT_SUCCESS;
}
int main(void) {
int i;
/* Lazy to calculate this size properly. */
char s[256];
/* Simple case. */
assert(str2int(&i, "11", 10) == STR2INT_SUCCESS);
assert(i == 11);
/* Negative number . */
assert(str2int(&i, "-11", 10) == STR2INT_SUCCESS);
assert(i == -11);
/* Different base. */
assert(str2int(&i, "11", 16) == STR2INT_SUCCESS);
assert(i == 17);
/* 0 */
assert(str2int(&i, "0", 10) == STR2INT_SUCCESS);
assert(i == 0);
/* INT_MAX. */
sprintf(s, "%d", INT_MAX);
assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
assert(i == INT_MAX);
/* INT_MIN. */
sprintf(s, "%d", INT_MIN);
assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
assert(i == INT_MIN);
/* Leading and trailing space. */
assert(str2int(&i, " 1", 10) == STR2INT_INCONVERTIBLE);
assert(str2int(&i, "1 ", 10) == STR2INT_INCONVERTIBLE);
/* Trash characters. */
assert(str2int(&i, "a10", 10) == STR2INT_INCONVERTIBLE);
assert(str2int(&i, "10a", 10) == STR2INT_INCONVERTIBLE);
/* int overflow.
*
* `if` needed to avoid undefined behaviour
* on `INT_MAX + 1` if INT_MAX == LONG_MAX.
*/
if (INT_MAX < LONG_MAX) {
sprintf(s, "%ld", (long int)INT_MAX + 1L);
assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
}
/* int underflow */
if (LONG_MIN < INT_MIN) {
sprintf(s, "%ld", (long int)INT_MIN - 1L);
assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
}
/* long overflow */
sprintf(s, "%ld0", LONG_MAX);
assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
/* long underflow */
sprintf(s, "%ld0", LONG_MIN);
assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
return EXIT_SUCCESS;
}
GitHub upstream.
Based on: https://stackoverflow.com/a/6154614/895245
3
Nice robuststr2int()
. Pedantic: useisspace((unsigned char) s[0])
.
– chux
May 30 '16 at 12:09
@chux thanks! Can you explain a bit more why the(unsigned char)
cast could make a difference?
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:00
1
@chux thanks! OMG, C is so hard :-) greenend.org.uk/rjk/tech/cfu.html
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:51
IAR C compiler warns thatl > INT_MAX
andl < INT_MIN
are pointless integer comparison since either result is always false. What happens if I change them tol >= INT_MAX
andl <= INT_MIN
to clear the warnings? On ARM C, long and int are 32-bit signed Basic data types in ARM C and C++
– ecle
Jan 26 '17 at 2:23
@ecle changing code tol >= INT_MAX
incurs incorrect functionality: Example returningSTR2INT_OVERFLOW
with input"32767"
and 16-bitint
. Use a conditional compile. Example.
– chux
Dec 20 '17 at 12:45
|
show 3 more comments
Robust C89 strtol
-based solution
With:
- no undefined behavior (as could be had with the
atoi
family) - a stricter definition of integer than
strtol
(e.g. no leading whitespace nor trailing trash chars) - classification of the error case (e.g. to give useful error messages to users)
- a "testsuite"
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
typedef enum {
STR2INT_SUCCESS,
STR2INT_OVERFLOW,
STR2INT_UNDERFLOW,
STR2INT_INCONVERTIBLE
} str2int_errno;
/* Convert string s to int out.
*
* @param[out] out The converted int. Cannot be NULL.
*
* @param[in] s Input string to be converted.
*
* The format is the same as strtol,
* except that the following are inconvertible:
*
* - empty string
* - leading whitespace
* - any trailing characters that are not part of the number
*
* Cannot be NULL.
*
* @param[in] base Base to interpret string in. Same range as strtol (2 to 36).
*
* @return Indicates if the operation succeeded, or why it failed.
*/
str2int_errno str2int(int *out, char *s, int base) {
char *end;
if (s[0] == '' || isspace(s[0]))
return STR2INT_INCONVERTIBLE;
errno = 0;
long l = strtol(s, &end, base);
/* Both checks are needed because INT_MAX == LONG_MAX is possible. */
if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
return STR2INT_OVERFLOW;
if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
return STR2INT_UNDERFLOW;
if (*end != '')
return STR2INT_INCONVERTIBLE;
*out = l;
return STR2INT_SUCCESS;
}
int main(void) {
int i;
/* Lazy to calculate this size properly. */
char s[256];
/* Simple case. */
assert(str2int(&i, "11", 10) == STR2INT_SUCCESS);
assert(i == 11);
/* Negative number . */
assert(str2int(&i, "-11", 10) == STR2INT_SUCCESS);
assert(i == -11);
/* Different base. */
assert(str2int(&i, "11", 16) == STR2INT_SUCCESS);
assert(i == 17);
/* 0 */
assert(str2int(&i, "0", 10) == STR2INT_SUCCESS);
assert(i == 0);
/* INT_MAX. */
sprintf(s, "%d", INT_MAX);
assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
assert(i == INT_MAX);
/* INT_MIN. */
sprintf(s, "%d", INT_MIN);
assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
assert(i == INT_MIN);
/* Leading and trailing space. */
assert(str2int(&i, " 1", 10) == STR2INT_INCONVERTIBLE);
assert(str2int(&i, "1 ", 10) == STR2INT_INCONVERTIBLE);
/* Trash characters. */
assert(str2int(&i, "a10", 10) == STR2INT_INCONVERTIBLE);
assert(str2int(&i, "10a", 10) == STR2INT_INCONVERTIBLE);
/* int overflow.
*
* `if` needed to avoid undefined behaviour
* on `INT_MAX + 1` if INT_MAX == LONG_MAX.
*/
if (INT_MAX < LONG_MAX) {
sprintf(s, "%ld", (long int)INT_MAX + 1L);
assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
}
/* int underflow */
if (LONG_MIN < INT_MIN) {
sprintf(s, "%ld", (long int)INT_MIN - 1L);
assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
}
/* long overflow */
sprintf(s, "%ld0", LONG_MAX);
assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
/* long underflow */
sprintf(s, "%ld0", LONG_MIN);
assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
return EXIT_SUCCESS;
}
GitHub upstream.
Based on: https://stackoverflow.com/a/6154614/895245
3
Nice robuststr2int()
. Pedantic: useisspace((unsigned char) s[0])
.
– chux
May 30 '16 at 12:09
@chux thanks! Can you explain a bit more why the(unsigned char)
cast could make a difference?
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:00
1
@chux thanks! OMG, C is so hard :-) greenend.org.uk/rjk/tech/cfu.html
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:51
IAR C compiler warns thatl > INT_MAX
andl < INT_MIN
are pointless integer comparison since either result is always false. What happens if I change them tol >= INT_MAX
andl <= INT_MIN
to clear the warnings? On ARM C, long and int are 32-bit signed Basic data types in ARM C and C++
– ecle
Jan 26 '17 at 2:23
@ecle changing code tol >= INT_MAX
incurs incorrect functionality: Example returningSTR2INT_OVERFLOW
with input"32767"
and 16-bitint
. Use a conditional compile. Example.
– chux
Dec 20 '17 at 12:45
|
show 3 more comments
Robust C89 strtol
-based solution
With:
- no undefined behavior (as could be had with the
atoi
family) - a stricter definition of integer than
strtol
(e.g. no leading whitespace nor trailing trash chars) - classification of the error case (e.g. to give useful error messages to users)
- a "testsuite"
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
typedef enum {
STR2INT_SUCCESS,
STR2INT_OVERFLOW,
STR2INT_UNDERFLOW,
STR2INT_INCONVERTIBLE
} str2int_errno;
/* Convert string s to int out.
*
* @param[out] out The converted int. Cannot be NULL.
*
* @param[in] s Input string to be converted.
*
* The format is the same as strtol,
* except that the following are inconvertible:
*
* - empty string
* - leading whitespace
* - any trailing characters that are not part of the number
*
* Cannot be NULL.
*
* @param[in] base Base to interpret string in. Same range as strtol (2 to 36).
*
* @return Indicates if the operation succeeded, or why it failed.
*/
str2int_errno str2int(int *out, char *s, int base) {
char *end;
if (s[0] == '' || isspace(s[0]))
return STR2INT_INCONVERTIBLE;
errno = 0;
long l = strtol(s, &end, base);
/* Both checks are needed because INT_MAX == LONG_MAX is possible. */
if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
return STR2INT_OVERFLOW;
if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
return STR2INT_UNDERFLOW;
if (*end != '')
return STR2INT_INCONVERTIBLE;
*out = l;
return STR2INT_SUCCESS;
}
int main(void) {
int i;
/* Lazy to calculate this size properly. */
char s[256];
/* Simple case. */
assert(str2int(&i, "11", 10) == STR2INT_SUCCESS);
assert(i == 11);
/* Negative number . */
assert(str2int(&i, "-11", 10) == STR2INT_SUCCESS);
assert(i == -11);
/* Different base. */
assert(str2int(&i, "11", 16) == STR2INT_SUCCESS);
assert(i == 17);
/* 0 */
assert(str2int(&i, "0", 10) == STR2INT_SUCCESS);
assert(i == 0);
/* INT_MAX. */
sprintf(s, "%d", INT_MAX);
assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
assert(i == INT_MAX);
/* INT_MIN. */
sprintf(s, "%d", INT_MIN);
assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
assert(i == INT_MIN);
/* Leading and trailing space. */
assert(str2int(&i, " 1", 10) == STR2INT_INCONVERTIBLE);
assert(str2int(&i, "1 ", 10) == STR2INT_INCONVERTIBLE);
/* Trash characters. */
assert(str2int(&i, "a10", 10) == STR2INT_INCONVERTIBLE);
assert(str2int(&i, "10a", 10) == STR2INT_INCONVERTIBLE);
/* int overflow.
*
* `if` needed to avoid undefined behaviour
* on `INT_MAX + 1` if INT_MAX == LONG_MAX.
*/
if (INT_MAX < LONG_MAX) {
sprintf(s, "%ld", (long int)INT_MAX + 1L);
assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
}
/* int underflow */
if (LONG_MIN < INT_MIN) {
sprintf(s, "%ld", (long int)INT_MIN - 1L);
assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
}
/* long overflow */
sprintf(s, "%ld0", LONG_MAX);
assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
/* long underflow */
sprintf(s, "%ld0", LONG_MIN);
assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
return EXIT_SUCCESS;
}
GitHub upstream.
Based on: https://stackoverflow.com/a/6154614/895245
Robust C89 strtol
-based solution
With:
- no undefined behavior (as could be had with the
atoi
family) - a stricter definition of integer than
strtol
(e.g. no leading whitespace nor trailing trash chars) - classification of the error case (e.g. to give useful error messages to users)
- a "testsuite"
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
typedef enum {
STR2INT_SUCCESS,
STR2INT_OVERFLOW,
STR2INT_UNDERFLOW,
STR2INT_INCONVERTIBLE
} str2int_errno;
/* Convert string s to int out.
*
* @param[out] out The converted int. Cannot be NULL.
*
* @param[in] s Input string to be converted.
*
* The format is the same as strtol,
* except that the following are inconvertible:
*
* - empty string
* - leading whitespace
* - any trailing characters that are not part of the number
*
* Cannot be NULL.
*
* @param[in] base Base to interpret string in. Same range as strtol (2 to 36).
*
* @return Indicates if the operation succeeded, or why it failed.
*/
str2int_errno str2int(int *out, char *s, int base) {
char *end;
if (s[0] == '' || isspace(s[0]))
return STR2INT_INCONVERTIBLE;
errno = 0;
long l = strtol(s, &end, base);
/* Both checks are needed because INT_MAX == LONG_MAX is possible. */
if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
return STR2INT_OVERFLOW;
if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
return STR2INT_UNDERFLOW;
if (*end != '')
return STR2INT_INCONVERTIBLE;
*out = l;
return STR2INT_SUCCESS;
}
int main(void) {
int i;
/* Lazy to calculate this size properly. */
char s[256];
/* Simple case. */
assert(str2int(&i, "11", 10) == STR2INT_SUCCESS);
assert(i == 11);
/* Negative number . */
assert(str2int(&i, "-11", 10) == STR2INT_SUCCESS);
assert(i == -11);
/* Different base. */
assert(str2int(&i, "11", 16) == STR2INT_SUCCESS);
assert(i == 17);
/* 0 */
assert(str2int(&i, "0", 10) == STR2INT_SUCCESS);
assert(i == 0);
/* INT_MAX. */
sprintf(s, "%d", INT_MAX);
assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
assert(i == INT_MAX);
/* INT_MIN. */
sprintf(s, "%d", INT_MIN);
assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
assert(i == INT_MIN);
/* Leading and trailing space. */
assert(str2int(&i, " 1", 10) == STR2INT_INCONVERTIBLE);
assert(str2int(&i, "1 ", 10) == STR2INT_INCONVERTIBLE);
/* Trash characters. */
assert(str2int(&i, "a10", 10) == STR2INT_INCONVERTIBLE);
assert(str2int(&i, "10a", 10) == STR2INT_INCONVERTIBLE);
/* int overflow.
*
* `if` needed to avoid undefined behaviour
* on `INT_MAX + 1` if INT_MAX == LONG_MAX.
*/
if (INT_MAX < LONG_MAX) {
sprintf(s, "%ld", (long int)INT_MAX + 1L);
assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
}
/* int underflow */
if (LONG_MIN < INT_MIN) {
sprintf(s, "%ld", (long int)INT_MIN - 1L);
assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
}
/* long overflow */
sprintf(s, "%ld0", LONG_MAX);
assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
/* long underflow */
sprintf(s, "%ld0", LONG_MIN);
assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
return EXIT_SUCCESS;
}
GitHub upstream.
Based on: https://stackoverflow.com/a/6154614/895245
edited Sep 1 '18 at 9:53
answered Oct 16 '12 at 21:46
Ciro Santilli 新疆改造中心996ICU六四事件Ciro Santilli 新疆改造中心996ICU六四事件
149k34560478
149k34560478
3
Nice robuststr2int()
. Pedantic: useisspace((unsigned char) s[0])
.
– chux
May 30 '16 at 12:09
@chux thanks! Can you explain a bit more why the(unsigned char)
cast could make a difference?
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:00
1
@chux thanks! OMG, C is so hard :-) greenend.org.uk/rjk/tech/cfu.html
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:51
IAR C compiler warns thatl > INT_MAX
andl < INT_MIN
are pointless integer comparison since either result is always false. What happens if I change them tol >= INT_MAX
andl <= INT_MIN
to clear the warnings? On ARM C, long and int are 32-bit signed Basic data types in ARM C and C++
– ecle
Jan 26 '17 at 2:23
@ecle changing code tol >= INT_MAX
incurs incorrect functionality: Example returningSTR2INT_OVERFLOW
with input"32767"
and 16-bitint
. Use a conditional compile. Example.
– chux
Dec 20 '17 at 12:45
|
show 3 more comments
3
Nice robuststr2int()
. Pedantic: useisspace((unsigned char) s[0])
.
– chux
May 30 '16 at 12:09
@chux thanks! Can you explain a bit more why the(unsigned char)
cast could make a difference?
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:00
1
@chux thanks! OMG, C is so hard :-) greenend.org.uk/rjk/tech/cfu.html
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:51
IAR C compiler warns thatl > INT_MAX
andl < INT_MIN
are pointless integer comparison since either result is always false. What happens if I change them tol >= INT_MAX
andl <= INT_MIN
to clear the warnings? On ARM C, long and int are 32-bit signed Basic data types in ARM C and C++
– ecle
Jan 26 '17 at 2:23
@ecle changing code tol >= INT_MAX
incurs incorrect functionality: Example returningSTR2INT_OVERFLOW
with input"32767"
and 16-bitint
. Use a conditional compile. Example.
– chux
Dec 20 '17 at 12:45
3
3
Nice robust
str2int()
. Pedantic: use isspace((unsigned char) s[0])
.– chux
May 30 '16 at 12:09
Nice robust
str2int()
. Pedantic: use isspace((unsigned char) s[0])
.– chux
May 30 '16 at 12:09
@chux thanks! Can you explain a bit more why the
(unsigned char)
cast could make a difference?– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:00
@chux thanks! Can you explain a bit more why the
(unsigned char)
cast could make a difference?– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:00
1
1
@chux thanks! OMG, C is so hard :-) greenend.org.uk/rjk/tech/cfu.html
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:51
@chux thanks! OMG, C is so hard :-) greenend.org.uk/rjk/tech/cfu.html
– Ciro Santilli 新疆改造中心996ICU六四事件
May 30 '16 at 13:51
IAR C compiler warns that
l > INT_MAX
and l < INT_MIN
are pointless integer comparison since either result is always false. What happens if I change them to l >= INT_MAX
and l <= INT_MIN
to clear the warnings? On ARM C, long and int are 32-bit signed Basic data types in ARM C and C++– ecle
Jan 26 '17 at 2:23
IAR C compiler warns that
l > INT_MAX
and l < INT_MIN
are pointless integer comparison since either result is always false. What happens if I change them to l >= INT_MAX
and l <= INT_MIN
to clear the warnings? On ARM C, long and int are 32-bit signed Basic data types in ARM C and C++– ecle
Jan 26 '17 at 2:23
@ecle changing code to
l >= INT_MAX
incurs incorrect functionality: Example returning STR2INT_OVERFLOW
with input "32767"
and 16-bit int
. Use a conditional compile. Example.– chux
Dec 20 '17 at 12:45
@ecle changing code to
l >= INT_MAX
incurs incorrect functionality: Example returning STR2INT_OVERFLOW
with input "32767"
and 16-bit int
. Use a conditional compile. Example.– chux
Dec 20 '17 at 12:45
|
show 3 more comments
Don't use functions from ato...
group. These are broken and virtually useless. A moderately better solution would be to use sscanf
, although it is not perfect either.
To convert string to integer, functions from strto...
group should be used. In your specific case it would be strtol
function.
7
sscanf
actually has undefined behavior if it tries to convert a number outside the range of its type (for example,sscanf("999999999999999999999", "%d", &n)
).
– Keith Thompson
Aug 11 '11 at 6:50
1
@Keith Thompson: That's exactly what I mean.atoi
provides no meaningful success/failure feedback and has undefined behavior on overflow.sscanf
provides success/failure feedback of sorts (the return value, which is what makes it "moderately better"), but still has undefined behavior on overflow. Onlystrtol
is a viable solution.
– AnT
Aug 11 '11 at 6:55
1
Agreed; I just wanted to emphasize the potentially fatal problem withsscanf
. (Though I confess I sometimes useatoi
, usually for programs that I don't expect to survive more than 10 minute before I delete the source.)
– Keith Thompson
Aug 11 '11 at 6:58
add a comment |
Don't use functions from ato...
group. These are broken and virtually useless. A moderately better solution would be to use sscanf
, although it is not perfect either.
To convert string to integer, functions from strto...
group should be used. In your specific case it would be strtol
function.
7
sscanf
actually has undefined behavior if it tries to convert a number outside the range of its type (for example,sscanf("999999999999999999999", "%d", &n)
).
– Keith Thompson
Aug 11 '11 at 6:50
1
@Keith Thompson: That's exactly what I mean.atoi
provides no meaningful success/failure feedback and has undefined behavior on overflow.sscanf
provides success/failure feedback of sorts (the return value, which is what makes it "moderately better"), but still has undefined behavior on overflow. Onlystrtol
is a viable solution.
– AnT
Aug 11 '11 at 6:55
1
Agreed; I just wanted to emphasize the potentially fatal problem withsscanf
. (Though I confess I sometimes useatoi
, usually for programs that I don't expect to survive more than 10 minute before I delete the source.)
– Keith Thompson
Aug 11 '11 at 6:58
add a comment |
Don't use functions from ato...
group. These are broken and virtually useless. A moderately better solution would be to use sscanf
, although it is not perfect either.
To convert string to integer, functions from strto...
group should be used. In your specific case it would be strtol
function.
Don't use functions from ato...
group. These are broken and virtually useless. A moderately better solution would be to use sscanf
, although it is not perfect either.
To convert string to integer, functions from strto...
group should be used. In your specific case it would be strtol
function.
edited Aug 11 '11 at 22:09
answered Aug 11 '11 at 6:34
AnTAnT
262k34424666
262k34424666
7
sscanf
actually has undefined behavior if it tries to convert a number outside the range of its type (for example,sscanf("999999999999999999999", "%d", &n)
).
– Keith Thompson
Aug 11 '11 at 6:50
1
@Keith Thompson: That's exactly what I mean.atoi
provides no meaningful success/failure feedback and has undefined behavior on overflow.sscanf
provides success/failure feedback of sorts (the return value, which is what makes it "moderately better"), but still has undefined behavior on overflow. Onlystrtol
is a viable solution.
– AnT
Aug 11 '11 at 6:55
1
Agreed; I just wanted to emphasize the potentially fatal problem withsscanf
. (Though I confess I sometimes useatoi
, usually for programs that I don't expect to survive more than 10 minute before I delete the source.)
– Keith Thompson
Aug 11 '11 at 6:58
add a comment |
7
sscanf
actually has undefined behavior if it tries to convert a number outside the range of its type (for example,sscanf("999999999999999999999", "%d", &n)
).
– Keith Thompson
Aug 11 '11 at 6:50
1
@Keith Thompson: That's exactly what I mean.atoi
provides no meaningful success/failure feedback and has undefined behavior on overflow.sscanf
provides success/failure feedback of sorts (the return value, which is what makes it "moderately better"), but still has undefined behavior on overflow. Onlystrtol
is a viable solution.
– AnT
Aug 11 '11 at 6:55
1
Agreed; I just wanted to emphasize the potentially fatal problem withsscanf
. (Though I confess I sometimes useatoi
, usually for programs that I don't expect to survive more than 10 minute before I delete the source.)
– Keith Thompson
Aug 11 '11 at 6:58
7
7
sscanf
actually has undefined behavior if it tries to convert a number outside the range of its type (for example, sscanf("999999999999999999999", "%d", &n)
).– Keith Thompson
Aug 11 '11 at 6:50
sscanf
actually has undefined behavior if it tries to convert a number outside the range of its type (for example, sscanf("999999999999999999999", "%d", &n)
).– Keith Thompson
Aug 11 '11 at 6:50
1
1
@Keith Thompson: That's exactly what I mean.
atoi
provides no meaningful success/failure feedback and has undefined behavior on overflow. sscanf
provides success/failure feedback of sorts (the return value, which is what makes it "moderately better"), but still has undefined behavior on overflow. Only strtol
is a viable solution.– AnT
Aug 11 '11 at 6:55
@Keith Thompson: That's exactly what I mean.
atoi
provides no meaningful success/failure feedback and has undefined behavior on overflow. sscanf
provides success/failure feedback of sorts (the return value, which is what makes it "moderately better"), but still has undefined behavior on overflow. Only strtol
is a viable solution.– AnT
Aug 11 '11 at 6:55
1
1
Agreed; I just wanted to emphasize the potentially fatal problem with
sscanf
. (Though I confess I sometimes use atoi
, usually for programs that I don't expect to survive more than 10 minute before I delete the source.)– Keith Thompson
Aug 11 '11 at 6:58
Agreed; I just wanted to emphasize the potentially fatal problem with
sscanf
. (Though I confess I sometimes use atoi
, usually for programs that I don't expect to survive more than 10 minute before I delete the source.)– Keith Thompson
Aug 11 '11 at 6:58
add a comment |
You can code a little atoi() for fun:
int my_getnbr(char *str)
{
int result;
int puiss;
result = 0;
puiss = 1;
while (('-' == (*str)) || ((*str) == '+'))
{
if (*str == '-')
puiss = puiss * -1;
str++;
}
while ((*str >= '0') && (*str <= '9'))
{
result = (result * 10) + ((*str) - '0');
str++;
}
return (result * puiss);
}
You can also make it recursive wich can old in 3 lines =)
Thanks so much .. But could you tell me how the below code works?code
((*str) - '0')code
– user618677
Aug 11 '11 at 16:15
a character has an ascii value. If you are uner linux type: man ascii in the shell or if not go to:table-ascii.com. You will see that the character '0' = 68 (i think) for a int. So to get the number of '9' (it's '0' + 9) so you get 9 = '9' - '0'. You get it?
– jDourlens
Aug 11 '11 at 16:31
1
1) The code allows"----1"
2) Has undefined behavior withint
overflow when the result should beINT_MIN
. Considermy_getnbr("-2147483648")
– chux
May 30 '16 at 12:12
Thanks for precision, it was just for showing a little example. As it's said it for fun and learning. You should definetly use standart lib for this kind of tasks. Faster and safer!
– jDourlens
Jun 1 '16 at 0:12
add a comment |
You can code a little atoi() for fun:
int my_getnbr(char *str)
{
int result;
int puiss;
result = 0;
puiss = 1;
while (('-' == (*str)) || ((*str) == '+'))
{
if (*str == '-')
puiss = puiss * -1;
str++;
}
while ((*str >= '0') && (*str <= '9'))
{
result = (result * 10) + ((*str) - '0');
str++;
}
return (result * puiss);
}
You can also make it recursive wich can old in 3 lines =)
Thanks so much .. But could you tell me how the below code works?code
((*str) - '0')code
– user618677
Aug 11 '11 at 16:15
a character has an ascii value. If you are uner linux type: man ascii in the shell or if not go to:table-ascii.com. You will see that the character '0' = 68 (i think) for a int. So to get the number of '9' (it's '0' + 9) so you get 9 = '9' - '0'. You get it?
– jDourlens
Aug 11 '11 at 16:31
1
1) The code allows"----1"
2) Has undefined behavior withint
overflow when the result should beINT_MIN
. Considermy_getnbr("-2147483648")
– chux
May 30 '16 at 12:12
Thanks for precision, it was just for showing a little example. As it's said it for fun and learning. You should definetly use standart lib for this kind of tasks. Faster and safer!
– jDourlens
Jun 1 '16 at 0:12
add a comment |
You can code a little atoi() for fun:
int my_getnbr(char *str)
{
int result;
int puiss;
result = 0;
puiss = 1;
while (('-' == (*str)) || ((*str) == '+'))
{
if (*str == '-')
puiss = puiss * -1;
str++;
}
while ((*str >= '0') && (*str <= '9'))
{
result = (result * 10) + ((*str) - '0');
str++;
}
return (result * puiss);
}
You can also make it recursive wich can old in 3 lines =)
You can code a little atoi() for fun:
int my_getnbr(char *str)
{
int result;
int puiss;
result = 0;
puiss = 1;
while (('-' == (*str)) || ((*str) == '+'))
{
if (*str == '-')
puiss = puiss * -1;
str++;
}
while ((*str >= '0') && (*str <= '9'))
{
result = (result * 10) + ((*str) - '0');
str++;
}
return (result * puiss);
}
You can also make it recursive wich can old in 3 lines =)
edited Sep 1 '18 at 18:11
vishal dharankar
4,68443767
4,68443767
answered Aug 11 '11 at 8:20
jDourlensjDourlens
1,57511529
1,57511529
Thanks so much .. But could you tell me how the below code works?code
((*str) - '0')code
– user618677
Aug 11 '11 at 16:15
a character has an ascii value. If you are uner linux type: man ascii in the shell or if not go to:table-ascii.com. You will see that the character '0' = 68 (i think) for a int. So to get the number of '9' (it's '0' + 9) so you get 9 = '9' - '0'. You get it?
– jDourlens
Aug 11 '11 at 16:31
1
1) The code allows"----1"
2) Has undefined behavior withint
overflow when the result should beINT_MIN
. Considermy_getnbr("-2147483648")
– chux
May 30 '16 at 12:12
Thanks for precision, it was just for showing a little example. As it's said it for fun and learning. You should definetly use standart lib for this kind of tasks. Faster and safer!
– jDourlens
Jun 1 '16 at 0:12
add a comment |
Thanks so much .. But could you tell me how the below code works?code
((*str) - '0')code
– user618677
Aug 11 '11 at 16:15
a character has an ascii value. If you are uner linux type: man ascii in the shell or if not go to:table-ascii.com. You will see that the character '0' = 68 (i think) for a int. So to get the number of '9' (it's '0' + 9) so you get 9 = '9' - '0'. You get it?
– jDourlens
Aug 11 '11 at 16:31
1
1) The code allows"----1"
2) Has undefined behavior withint
overflow when the result should beINT_MIN
. Considermy_getnbr("-2147483648")
– chux
May 30 '16 at 12:12
Thanks for precision, it was just for showing a little example. As it's said it for fun and learning. You should definetly use standart lib for this kind of tasks. Faster and safer!
– jDourlens
Jun 1 '16 at 0:12
Thanks so much .. But could you tell me how the below code works?
code
((*str) - '0') code
– user618677
Aug 11 '11 at 16:15
Thanks so much .. But could you tell me how the below code works?
code
((*str) - '0') code
– user618677
Aug 11 '11 at 16:15
a character has an ascii value. If you are uner linux type: man ascii in the shell or if not go to:table-ascii.com. You will see that the character '0' = 68 (i think) for a int. So to get the number of '9' (it's '0' + 9) so you get 9 = '9' - '0'. You get it?
– jDourlens
Aug 11 '11 at 16:31
a character has an ascii value. If you are uner linux type: man ascii in the shell or if not go to:table-ascii.com. You will see that the character '0' = 68 (i think) for a int. So to get the number of '9' (it's '0' + 9) so you get 9 = '9' - '0'. You get it?
– jDourlens
Aug 11 '11 at 16:31
1
1
1) The code allows
"----1"
2) Has undefined behavior with int
overflow when the result should be INT_MIN
. Consider my_getnbr("-2147483648")
– chux
May 30 '16 at 12:12
1) The code allows
"----1"
2) Has undefined behavior with int
overflow when the result should be INT_MIN
. Consider my_getnbr("-2147483648")
– chux
May 30 '16 at 12:12
Thanks for precision, it was just for showing a little example. As it's said it for fun and learning. You should definetly use standart lib for this kind of tasks. Faster and safer!
– jDourlens
Jun 1 '16 at 0:12
Thanks for precision, it was just for showing a little example. As it's said it for fun and learning. You should definetly use standart lib for this kind of tasks. Faster and safer!
– jDourlens
Jun 1 '16 at 0:12
add a comment |
Just wanted to share a solution for unsigned long aswell.
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
1
Doesn't handle overflow. Also, the parameter should beconst char *
.
– Roland Illig
Jan 21 '17 at 17:35
1
Plus, what's that48
mean? Are you assuming that's the value of'0'
where the code will run? Please don't inflict such broad assumptions on the world!
– Toby Speight
Jun 18 '18 at 16:15
@TobySpeight Yes I assume 48 represent '0' in the ascii table.
– Jacob
Jun 20 '18 at 9:17
1
Not all the world is ASCII - just use'0'
like you should.
– Toby Speight
Jun 20 '18 at 10:42
add a comment |
Just wanted to share a solution for unsigned long aswell.
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
1
Doesn't handle overflow. Also, the parameter should beconst char *
.
– Roland Illig
Jan 21 '17 at 17:35
1
Plus, what's that48
mean? Are you assuming that's the value of'0'
where the code will run? Please don't inflict such broad assumptions on the world!
– Toby Speight
Jun 18 '18 at 16:15
@TobySpeight Yes I assume 48 represent '0' in the ascii table.
– Jacob
Jun 20 '18 at 9:17
1
Not all the world is ASCII - just use'0'
like you should.
– Toby Speight
Jun 20 '18 at 10:42
add a comment |
Just wanted to share a solution for unsigned long aswell.
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
Just wanted to share a solution for unsigned long aswell.
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
answered Oct 18 '16 at 19:26
JacobJacob
1488
1488
1
Doesn't handle overflow. Also, the parameter should beconst char *
.
– Roland Illig
Jan 21 '17 at 17:35
1
Plus, what's that48
mean? Are you assuming that's the value of'0'
where the code will run? Please don't inflict such broad assumptions on the world!
– Toby Speight
Jun 18 '18 at 16:15
@TobySpeight Yes I assume 48 represent '0' in the ascii table.
– Jacob
Jun 20 '18 at 9:17
1
Not all the world is ASCII - just use'0'
like you should.
– Toby Speight
Jun 20 '18 at 10:42
add a comment |
1
Doesn't handle overflow. Also, the parameter should beconst char *
.
– Roland Illig
Jan 21 '17 at 17:35
1
Plus, what's that48
mean? Are you assuming that's the value of'0'
where the code will run? Please don't inflict such broad assumptions on the world!
– Toby Speight
Jun 18 '18 at 16:15
@TobySpeight Yes I assume 48 represent '0' in the ascii table.
– Jacob
Jun 20 '18 at 9:17
1
Not all the world is ASCII - just use'0'
like you should.
– Toby Speight
Jun 20 '18 at 10:42
1
1
Doesn't handle overflow. Also, the parameter should be
const char *
.– Roland Illig
Jan 21 '17 at 17:35
Doesn't handle overflow. Also, the parameter should be
const char *
.– Roland Illig
Jan 21 '17 at 17:35
1
1
Plus, what's that
48
mean? Are you assuming that's the value of '0'
where the code will run? Please don't inflict such broad assumptions on the world!– Toby Speight
Jun 18 '18 at 16:15
Plus, what's that
48
mean? Are you assuming that's the value of '0'
where the code will run? Please don't inflict such broad assumptions on the world!– Toby Speight
Jun 18 '18 at 16:15
@TobySpeight Yes I assume 48 represent '0' in the ascii table.
– Jacob
Jun 20 '18 at 9:17
@TobySpeight Yes I assume 48 represent '0' in the ascii table.
– Jacob
Jun 20 '18 at 9:17
1
1
Not all the world is ASCII - just use
'0'
like you should.– Toby Speight
Jun 20 '18 at 10:42
Not all the world is ASCII - just use
'0'
like you should.– Toby Speight
Jun 20 '18 at 10:42
add a comment |
This function will help you
int strtoint_n(char* str, int n)
{
int sign = 1;
int place = 1;
int ret = 0;
int i;
for (i = n-1; i >= 0; i--, place *= 10)
{
int c = str[i];
switch (c)
{
case '-':
if (i == 0) sign = -1;
else return -1;
break;
default:
if (c >= '0' && c <= '9') ret += (c - '0') * place;
else return -1;
}
}
return sign * ret;
}
int strtoint(char* str)
{
char* temp = str;
int n = 0;
while (*temp != '')
{
n++;
temp++;
}
return strtoint_n(str, n);
}
Ref: http://amscata.blogspot.com/2013/09/strnumstr-version-2.html
1
Why do this though? One of the biggest problems withatoi
and friends is that if there's overflow, it's undefined behavior. Your function does not check for this.strtol
and friends do.
– chad
Sep 2 '15 at 19:45
1
Yup. Since C is not Python I hope that the people who use C language are aware of these kind of overflow errors. Everything has it's own limits.
– Amith Chinthaka
Sep 3 '15 at 9:04
add a comment |
This function will help you
int strtoint_n(char* str, int n)
{
int sign = 1;
int place = 1;
int ret = 0;
int i;
for (i = n-1; i >= 0; i--, place *= 10)
{
int c = str[i];
switch (c)
{
case '-':
if (i == 0) sign = -1;
else return -1;
break;
default:
if (c >= '0' && c <= '9') ret += (c - '0') * place;
else return -1;
}
}
return sign * ret;
}
int strtoint(char* str)
{
char* temp = str;
int n = 0;
while (*temp != '')
{
n++;
temp++;
}
return strtoint_n(str, n);
}
Ref: http://amscata.blogspot.com/2013/09/strnumstr-version-2.html
1
Why do this though? One of the biggest problems withatoi
and friends is that if there's overflow, it's undefined behavior. Your function does not check for this.strtol
and friends do.
– chad
Sep 2 '15 at 19:45
1
Yup. Since C is not Python I hope that the people who use C language are aware of these kind of overflow errors. Everything has it's own limits.
– Amith Chinthaka
Sep 3 '15 at 9:04
add a comment |
This function will help you
int strtoint_n(char* str, int n)
{
int sign = 1;
int place = 1;
int ret = 0;
int i;
for (i = n-1; i >= 0; i--, place *= 10)
{
int c = str[i];
switch (c)
{
case '-':
if (i == 0) sign = -1;
else return -1;
break;
default:
if (c >= '0' && c <= '9') ret += (c - '0') * place;
else return -1;
}
}
return sign * ret;
}
int strtoint(char* str)
{
char* temp = str;
int n = 0;
while (*temp != '')
{
n++;
temp++;
}
return strtoint_n(str, n);
}
Ref: http://amscata.blogspot.com/2013/09/strnumstr-version-2.html
This function will help you
int strtoint_n(char* str, int n)
{
int sign = 1;
int place = 1;
int ret = 0;
int i;
for (i = n-1; i >= 0; i--, place *= 10)
{
int c = str[i];
switch (c)
{
case '-':
if (i == 0) sign = -1;
else return -1;
break;
default:
if (c >= '0' && c <= '9') ret += (c - '0') * place;
else return -1;
}
}
return sign * ret;
}
int strtoint(char* str)
{
char* temp = str;
int n = 0;
while (*temp != '')
{
n++;
temp++;
}
return strtoint_n(str, n);
}
Ref: http://amscata.blogspot.com/2013/09/strnumstr-version-2.html
edited Aug 7 '15 at 16:35
MC93
762714
762714
answered Sep 12 '13 at 11:31
Amith ChinthakaAmith Chinthaka
5431122
5431122
1
Why do this though? One of the biggest problems withatoi
and friends is that if there's overflow, it's undefined behavior. Your function does not check for this.strtol
and friends do.
– chad
Sep 2 '15 at 19:45
1
Yup. Since C is not Python I hope that the people who use C language are aware of these kind of overflow errors. Everything has it's own limits.
– Amith Chinthaka
Sep 3 '15 at 9:04
add a comment |
1
Why do this though? One of the biggest problems withatoi
and friends is that if there's overflow, it's undefined behavior. Your function does not check for this.strtol
and friends do.
– chad
Sep 2 '15 at 19:45
1
Yup. Since C is not Python I hope that the people who use C language are aware of these kind of overflow errors. Everything has it's own limits.
– Amith Chinthaka
Sep 3 '15 at 9:04
1
1
Why do this though? One of the biggest problems with
atoi
and friends is that if there's overflow, it's undefined behavior. Your function does not check for this. strtol
and friends do.– chad
Sep 2 '15 at 19:45
Why do this though? One of the biggest problems with
atoi
and friends is that if there's overflow, it's undefined behavior. Your function does not check for this. strtol
and friends do.– chad
Sep 2 '15 at 19:45
1
1
Yup. Since C is not Python I hope that the people who use C language are aware of these kind of overflow errors. Everything has it's own limits.
– Amith Chinthaka
Sep 3 '15 at 9:04
Yup. Since C is not Python I hope that the people who use C language are aware of these kind of overflow errors. Everything has it's own limits.
– Amith Chinthaka
Sep 3 '15 at 9:04
add a comment |
Ok, I had the same problem.I came up with this solution.It worked for me the best.I did try atoi() but didn't work well for me.So here is my solution:
void splitInput(int arr, int sizeArr, char num)
{
for(int i = 0; i < sizeArr; i++)
// We are subtracting 48 because the numbers in ASCII starts at 48.
arr[i] = (int)num[i] - 48;
}
add a comment |
Ok, I had the same problem.I came up with this solution.It worked for me the best.I did try atoi() but didn't work well for me.So here is my solution:
void splitInput(int arr, int sizeArr, char num)
{
for(int i = 0; i < sizeArr; i++)
// We are subtracting 48 because the numbers in ASCII starts at 48.
arr[i] = (int)num[i] - 48;
}
add a comment |
Ok, I had the same problem.I came up with this solution.It worked for me the best.I did try atoi() but didn't work well for me.So here is my solution:
void splitInput(int arr, int sizeArr, char num)
{
for(int i = 0; i < sizeArr; i++)
// We are subtracting 48 because the numbers in ASCII starts at 48.
arr[i] = (int)num[i] - 48;
}
Ok, I had the same problem.I came up with this solution.It worked for me the best.I did try atoi() but didn't work well for me.So here is my solution:
void splitInput(int arr, int sizeArr, char num)
{
for(int i = 0; i < sizeArr; i++)
// We are subtracting 48 because the numbers in ASCII starts at 48.
arr[i] = (int)num[i] - 48;
}
answered Sep 5 '15 at 15:36
Khaled MohammadKhaled Mohammad
1347
1347
add a comment |
add a comment |
//I think this way we could go :
int my_atoi(const char* snum)
{
int nInt(0);
int index(0);
while(snum[index])
{
if(!nInt)
nInt= ( (int) snum[index]) - 48;
else
{
nInt = (nInt *= 10) + ((int) snum[index] - 48);
}
index++;
}
return(nInt);
}
int main()
{
printf("Returned number is: %dn", my_atoi("676987"));
return 0;
}
Code does not compile in C. WhynInt = (nInt *= 10) + ((int) snum[index] - 48);
vs.nInt = nInt*10 + snum[index] - '0';
if(!nInt)
not needed.
– chux
May 30 '16 at 12:19
add a comment |
//I think this way we could go :
int my_atoi(const char* snum)
{
int nInt(0);
int index(0);
while(snum[index])
{
if(!nInt)
nInt= ( (int) snum[index]) - 48;
else
{
nInt = (nInt *= 10) + ((int) snum[index] - 48);
}
index++;
}
return(nInt);
}
int main()
{
printf("Returned number is: %dn", my_atoi("676987"));
return 0;
}
Code does not compile in C. WhynInt = (nInt *= 10) + ((int) snum[index] - 48);
vs.nInt = nInt*10 + snum[index] - '0';
if(!nInt)
not needed.
– chux
May 30 '16 at 12:19
add a comment |
//I think this way we could go :
int my_atoi(const char* snum)
{
int nInt(0);
int index(0);
while(snum[index])
{
if(!nInt)
nInt= ( (int) snum[index]) - 48;
else
{
nInt = (nInt *= 10) + ((int) snum[index] - 48);
}
index++;
}
return(nInt);
}
int main()
{
printf("Returned number is: %dn", my_atoi("676987"));
return 0;
}
//I think this way we could go :
int my_atoi(const char* snum)
{
int nInt(0);
int index(0);
while(snum[index])
{
if(!nInt)
nInt= ( (int) snum[index]) - 48;
else
{
nInt = (nInt *= 10) + ((int) snum[index] - 48);
}
index++;
}
return(nInt);
}
int main()
{
printf("Returned number is: %dn", my_atoi("676987"));
return 0;
}
answered Nov 6 '15 at 13:05
Aditya KumarAditya Kumar
673
673
Code does not compile in C. WhynInt = (nInt *= 10) + ((int) snum[index] - 48);
vs.nInt = nInt*10 + snum[index] - '0';
if(!nInt)
not needed.
– chux
May 30 '16 at 12:19
add a comment |
Code does not compile in C. WhynInt = (nInt *= 10) + ((int) snum[index] - 48);
vs.nInt = nInt*10 + snum[index] - '0';
if(!nInt)
not needed.
– chux
May 30 '16 at 12:19
Code does not compile in C. Why
nInt = (nInt *= 10) + ((int) snum[index] - 48);
vs. nInt = nInt*10 + snum[index] - '0';
if(!nInt)
not needed.– chux
May 30 '16 at 12:19
Code does not compile in C. Why
nInt = (nInt *= 10) + ((int) snum[index] - 48);
vs. nInt = nInt*10 + snum[index] - '0';
if(!nInt)
not needed.– chux
May 30 '16 at 12:19
add a comment |
You can always roll your own!
#include <stdio.h>
#include <string.h>
#include <math.h>
int my_atoi(const char* snum)
{
int idx, strIdx = 0, accum = 0, numIsNeg = 0;
const unsigned int NUMLEN = (int)strlen(snum);
/* Check if negative number and flag it. */
if(snum[0] == 0x2d)
numIsNeg = 1;
for(idx = NUMLEN - 1; idx >= 0; idx--)
{
/* Only process numbers from 0 through 9. */
if(snum[strIdx] >= 0x30 && snum[strIdx] <= 0x39)
accum += (snum[strIdx] - 0x30) * pow(10, idx);
strIdx++;
}
/* Check flag to see if originally passed -ve number and convert result if so. */
if(!numIsNeg)
return accum;
else
return accum * -1;
}
int main()
{
/* Tests... */
printf("Returned number is: %dn", my_atoi("34574"));
printf("Returned number is: %dn", my_atoi("-23"));
return 0;
}
This will do what you want without clutter.
2
But... why? This doesn't check for overflow and simply ignores garbage values. There's no reason not to use thestrto...
family of functions. They are portable and significantly better.
– chad
Sep 2 '15 at 19:41
1
Strange to use0x2d, 0x30
instead of'-', '0'
. Does not allow'+'
sign. Why(int)
cast in(int)strlen(snum)
? UB if input is""
. UB when result isINT_MIN
due toint
overflow withaccum += (snum[strIdx] - 0x30) * pow(10, idx);
– chux
May 30 '16 at 12:24
@chux - This code is demonstration code. There are easy fixes to what you described as potential issues.
– ButchDean
Jun 7 '16 at 4:12
1
@ButchDean What you describe as "demonstration code" will be used by others who have no clue about all the details. Only the negative score and the comments on this answer protect them now. In my opinion, "demonstration code" must have much higher quality.
– Roland Illig
Jan 21 '17 at 17:39
@RolandIllig Rather than being all critical, wouldn't it be more helpful to others to actually put up your own solution?
– ButchDean
Jan 24 '17 at 17:35
|
show 6 more comments
You can always roll your own!
#include <stdio.h>
#include <string.h>
#include <math.h>
int my_atoi(const char* snum)
{
int idx, strIdx = 0, accum = 0, numIsNeg = 0;
const unsigned int NUMLEN = (int)strlen(snum);
/* Check if negative number and flag it. */
if(snum[0] == 0x2d)
numIsNeg = 1;
for(idx = NUMLEN - 1; idx >= 0; idx--)
{
/* Only process numbers from 0 through 9. */
if(snum[strIdx] >= 0x30 && snum[strIdx] <= 0x39)
accum += (snum[strIdx] - 0x30) * pow(10, idx);
strIdx++;
}
/* Check flag to see if originally passed -ve number and convert result if so. */
if(!numIsNeg)
return accum;
else
return accum * -1;
}
int main()
{
/* Tests... */
printf("Returned number is: %dn", my_atoi("34574"));
printf("Returned number is: %dn", my_atoi("-23"));
return 0;
}
This will do what you want without clutter.
2
But... why? This doesn't check for overflow and simply ignores garbage values. There's no reason not to use thestrto...
family of functions. They are portable and significantly better.
– chad
Sep 2 '15 at 19:41
1
Strange to use0x2d, 0x30
instead of'-', '0'
. Does not allow'+'
sign. Why(int)
cast in(int)strlen(snum)
? UB if input is""
. UB when result isINT_MIN
due toint
overflow withaccum += (snum[strIdx] - 0x30) * pow(10, idx);
– chux
May 30 '16 at 12:24
@chux - This code is demonstration code. There are easy fixes to what you described as potential issues.
– ButchDean
Jun 7 '16 at 4:12
1
@ButchDean What you describe as "demonstration code" will be used by others who have no clue about all the details. Only the negative score and the comments on this answer protect them now. In my opinion, "demonstration code" must have much higher quality.
– Roland Illig
Jan 21 '17 at 17:39
@RolandIllig Rather than being all critical, wouldn't it be more helpful to others to actually put up your own solution?
– ButchDean
Jan 24 '17 at 17:35
|
show 6 more comments
You can always roll your own!
#include <stdio.h>
#include <string.h>
#include <math.h>
int my_atoi(const char* snum)
{
int idx, strIdx = 0, accum = 0, numIsNeg = 0;
const unsigned int NUMLEN = (int)strlen(snum);
/* Check if negative number and flag it. */
if(snum[0] == 0x2d)
numIsNeg = 1;
for(idx = NUMLEN - 1; idx >= 0; idx--)
{
/* Only process numbers from 0 through 9. */
if(snum[strIdx] >= 0x30 && snum[strIdx] <= 0x39)
accum += (snum[strIdx] - 0x30) * pow(10, idx);
strIdx++;
}
/* Check flag to see if originally passed -ve number and convert result if so. */
if(!numIsNeg)
return accum;
else
return accum * -1;
}
int main()
{
/* Tests... */
printf("Returned number is: %dn", my_atoi("34574"));
printf("Returned number is: %dn", my_atoi("-23"));
return 0;
}
This will do what you want without clutter.
You can always roll your own!
#include <stdio.h>
#include <string.h>
#include <math.h>
int my_atoi(const char* snum)
{
int idx, strIdx = 0, accum = 0, numIsNeg = 0;
const unsigned int NUMLEN = (int)strlen(snum);
/* Check if negative number and flag it. */
if(snum[0] == 0x2d)
numIsNeg = 1;
for(idx = NUMLEN - 1; idx >= 0; idx--)
{
/* Only process numbers from 0 through 9. */
if(snum[strIdx] >= 0x30 && snum[strIdx] <= 0x39)
accum += (snum[strIdx] - 0x30) * pow(10, idx);
strIdx++;
}
/* Check flag to see if originally passed -ve number and convert result if so. */
if(!numIsNeg)
return accum;
else
return accum * -1;
}
int main()
{
/* Tests... */
printf("Returned number is: %dn", my_atoi("34574"));
printf("Returned number is: %dn", my_atoi("-23"));
return 0;
}
This will do what you want without clutter.
answered Jan 3 '15 at 0:42
ButchDeanButchDean
746
746
2
But... why? This doesn't check for overflow and simply ignores garbage values. There's no reason not to use thestrto...
family of functions. They are portable and significantly better.
– chad
Sep 2 '15 at 19:41
1
Strange to use0x2d, 0x30
instead of'-', '0'
. Does not allow'+'
sign. Why(int)
cast in(int)strlen(snum)
? UB if input is""
. UB when result isINT_MIN
due toint
overflow withaccum += (snum[strIdx] - 0x30) * pow(10, idx);
– chux
May 30 '16 at 12:24
@chux - This code is demonstration code. There are easy fixes to what you described as potential issues.
– ButchDean
Jun 7 '16 at 4:12
1
@ButchDean What you describe as "demonstration code" will be used by others who have no clue about all the details. Only the negative score and the comments on this answer protect them now. In my opinion, "demonstration code" must have much higher quality.
– Roland Illig
Jan 21 '17 at 17:39
@RolandIllig Rather than being all critical, wouldn't it be more helpful to others to actually put up your own solution?
– ButchDean
Jan 24 '17 at 17:35
|
show 6 more comments
2
But... why? This doesn't check for overflow and simply ignores garbage values. There's no reason not to use thestrto...
family of functions. They are portable and significantly better.
– chad
Sep 2 '15 at 19:41
1
Strange to use0x2d, 0x30
instead of'-', '0'
. Does not allow'+'
sign. Why(int)
cast in(int)strlen(snum)
? UB if input is""
. UB when result isINT_MIN
due toint
overflow withaccum += (snum[strIdx] - 0x30) * pow(10, idx);
– chux
May 30 '16 at 12:24
@chux - This code is demonstration code. There are easy fixes to what you described as potential issues.
– ButchDean
Jun 7 '16 at 4:12
1
@ButchDean What you describe as "demonstration code" will be used by others who have no clue about all the details. Only the negative score and the comments on this answer protect them now. In my opinion, "demonstration code" must have much higher quality.
– Roland Illig
Jan 21 '17 at 17:39
@RolandIllig Rather than being all critical, wouldn't it be more helpful to others to actually put up your own solution?
– ButchDean
Jan 24 '17 at 17:35
2
2
But... why? This doesn't check for overflow and simply ignores garbage values. There's no reason not to use the
strto...
family of functions. They are portable and significantly better.– chad
Sep 2 '15 at 19:41
But... why? This doesn't check for overflow and simply ignores garbage values. There's no reason not to use the
strto...
family of functions. They are portable and significantly better.– chad
Sep 2 '15 at 19:41
1
1
Strange to use
0x2d, 0x30
instead of '-', '0'
. Does not allow '+'
sign. Why (int)
cast in (int)strlen(snum)
? UB if input is ""
. UB when result is INT_MIN
due to int
overflow with accum += (snum[strIdx] - 0x30) * pow(10, idx);
– chux
May 30 '16 at 12:24
Strange to use
0x2d, 0x30
instead of '-', '0'
. Does not allow '+'
sign. Why (int)
cast in (int)strlen(snum)
? UB if input is ""
. UB when result is INT_MIN
due to int
overflow with accum += (snum[strIdx] - 0x30) * pow(10, idx);
– chux
May 30 '16 at 12:24
@chux - This code is demonstration code. There are easy fixes to what you described as potential issues.
– ButchDean
Jun 7 '16 at 4:12
@chux - This code is demonstration code. There are easy fixes to what you described as potential issues.
– ButchDean
Jun 7 '16 at 4:12
1
1
@ButchDean What you describe as "demonstration code" will be used by others who have no clue about all the details. Only the negative score and the comments on this answer protect them now. In my opinion, "demonstration code" must have much higher quality.
– Roland Illig
Jan 21 '17 at 17:39
@ButchDean What you describe as "demonstration code" will be used by others who have no clue about all the details. Only the negative score and the comments on this answer protect them now. In my opinion, "demonstration code" must have much higher quality.
– Roland Illig
Jan 21 '17 at 17:39
@RolandIllig Rather than being all critical, wouldn't it be more helpful to others to actually put up your own solution?
– ButchDean
Jan 24 '17 at 17:35
@RolandIllig Rather than being all critical, wouldn't it be more helpful to others to actually put up your own solution?
– ButchDean
Jan 24 '17 at 17:35
|
show 6 more comments
In C++, you can use a such function:
template <typename T>
T to(const std::string & s)
{
std::istringstream stm(s);
T result;
stm >> result;
if(stm.tellg() != s.size())
throw error;
return result;
}
This can help you to convert any string to any type such as float, int, double...
1
There's already a similar question covering C++, where the problems with this approach are explained.
– Ben Voigt
Feb 20 '15 at 17:28
add a comment |
In C++, you can use a such function:
template <typename T>
T to(const std::string & s)
{
std::istringstream stm(s);
T result;
stm >> result;
if(stm.tellg() != s.size())
throw error;
return result;
}
This can help you to convert any string to any type such as float, int, double...
1
There's already a similar question covering C++, where the problems with this approach are explained.
– Ben Voigt
Feb 20 '15 at 17:28
add a comment |
In C++, you can use a such function:
template <typename T>
T to(const std::string & s)
{
std::istringstream stm(s);
T result;
stm >> result;
if(stm.tellg() != s.size())
throw error;
return result;
}
This can help you to convert any string to any type such as float, int, double...
In C++, you can use a such function:
template <typename T>
T to(const std::string & s)
{
std::istringstream stm(s);
T result;
stm >> result;
if(stm.tellg() != s.size())
throw error;
return result;
}
This can help you to convert any string to any type such as float, int, double...
answered Aug 11 '11 at 6:41
neodelphineodelphi
2,06411017
2,06411017
1
There's already a similar question covering C++, where the problems with this approach are explained.
– Ben Voigt
Feb 20 '15 at 17:28
add a comment |
1
There's already a similar question covering C++, where the problems with this approach are explained.
– Ben Voigt
Feb 20 '15 at 17:28
1
1
There's already a similar question covering C++, where the problems with this approach are explained.
– Ben Voigt
Feb 20 '15 at 17:28
There's already a similar question covering C++, where the problems with this approach are explained.
– Ben Voigt
Feb 20 '15 at 17:28
add a comment |
Yes, you can store the integer directly:
int num = 45;
If you must parse a string, atoi
or strol
is going to win the "shortest amount of code" contest.
If you want to do it safely,strtol()
actually requires a fair amount of code. It can returnLONG_MIN
orLONG_MAX
either if that's the actual converted value or if there's an underflow or overflow, and it can return 0 either if that's the actual value or if there was no number to convert. You need to seterrno = 0
before the call, and check theendptr
.
– Keith Thompson
Aug 11 '11 at 6:54
The solutions given to parse, are no viable solutions.
– BananaAcid
Feb 1 '18 at 21:15
add a comment |
Yes, you can store the integer directly:
int num = 45;
If you must parse a string, atoi
or strol
is going to win the "shortest amount of code" contest.
If you want to do it safely,strtol()
actually requires a fair amount of code. It can returnLONG_MIN
orLONG_MAX
either if that's the actual converted value or if there's an underflow or overflow, and it can return 0 either if that's the actual value or if there was no number to convert. You need to seterrno = 0
before the call, and check theendptr
.
– Keith Thompson
Aug 11 '11 at 6:54
The solutions given to parse, are no viable solutions.
– BananaAcid
Feb 1 '18 at 21:15
add a comment |
Yes, you can store the integer directly:
int num = 45;
If you must parse a string, atoi
or strol
is going to win the "shortest amount of code" contest.
Yes, you can store the integer directly:
int num = 45;
If you must parse a string, atoi
or strol
is going to win the "shortest amount of code" contest.
answered Aug 11 '11 at 6:32
Yann RaminYann Ramin
30.6k14776
30.6k14776
If you want to do it safely,strtol()
actually requires a fair amount of code. It can returnLONG_MIN
orLONG_MAX
either if that's the actual converted value or if there's an underflow or overflow, and it can return 0 either if that's the actual value or if there was no number to convert. You need to seterrno = 0
before the call, and check theendptr
.
– Keith Thompson
Aug 11 '11 at 6:54
The solutions given to parse, are no viable solutions.
– BananaAcid
Feb 1 '18 at 21:15
add a comment |
If you want to do it safely,strtol()
actually requires a fair amount of code. It can returnLONG_MIN
orLONG_MAX
either if that's the actual converted value or if there's an underflow or overflow, and it can return 0 either if that's the actual value or if there was no number to convert. You need to seterrno = 0
before the call, and check theendptr
.
– Keith Thompson
Aug 11 '11 at 6:54
The solutions given to parse, are no viable solutions.
– BananaAcid
Feb 1 '18 at 21:15
If you want to do it safely,
strtol()
actually requires a fair amount of code. It can return LONG_MIN
or LONG_MAX
either if that's the actual converted value or if there's an underflow or overflow, and it can return 0 either if that's the actual value or if there was no number to convert. You need to set errno = 0
before the call, and check the endptr
.– Keith Thompson
Aug 11 '11 at 6:54
If you want to do it safely,
strtol()
actually requires a fair amount of code. It can return LONG_MIN
or LONG_MAX
either if that's the actual converted value or if there's an underflow or overflow, and it can return 0 either if that's the actual value or if there was no number to convert. You need to set errno = 0
before the call, and check the endptr
.– Keith Thompson
Aug 11 '11 at 6:54
The solutions given to parse, are no viable solutions.
– BananaAcid
Feb 1 '18 at 21:15
The solutions given to parse, are no viable solutions.
– BananaAcid
Feb 1 '18 at 21:15
add a comment |
protected by Mysticial Mar 15 '14 at 21:52
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
20
Your tags and title say you want a solution in C, but your question says C or C++. Which one do you want?
– In silico
Aug 11 '11 at 6:32
1
@Yann, Sorry for that confusion. I will prefer C .
– user618677
Aug 11 '11 at 16:16
1
It works, but it's not the recommended way, because there is no way to handle errors. Never use this in production code unless you can trust the input 100%.
– Uwe Geuder
Nov 5 '15 at 17:47
1
Define 'better', and state clearly why you need another way.
– user207421
Jun 18 '18 at 10:35
1
@EJP Just to improve myself.
– user618677
Aug 3 '18 at 1:32