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;
}







218















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?










share|improve this question




















  • 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


















218















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?










share|improve this question




















  • 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














218












218








218


74






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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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














  • 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












11 Answers
11






active

oldest

votes


















158














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
.







share|improve this answer


























  • 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






  • 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



















23














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






share|improve this answer





















  • 3





    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






  • 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 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



















21














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.






share|improve this answer





















  • 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. Only strtol is a viable solution.

    – AnT
    Aug 11 '11 at 6:55








  • 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



















5














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 =)






share|improve this answer


























  • 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 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



















2














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;
}





share|improve this answer



















  • 1





    Doesn't handle overflow. Also, the parameter should be const char *.

    – Roland Illig
    Jan 21 '17 at 17:35








  • 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











  • @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



















0














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






share|improve this answer





















  • 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






  • 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



















0














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;
}





share|improve this answer































    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;
    }





    share|improve this answer
























    • 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



















    -1














    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.






    share|improve this answer



















    • 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






    • 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











    • @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



















    -3














    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...






    share|improve this answer



















    • 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



















    -4














    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.






    share|improve this answer
























    • 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










    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









    158














    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
    .







    share|improve this answer


























    • 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






    • 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
















    158














    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
    .







    share|improve this answer


























    • 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






    • 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














    158












    158








    158







    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
    .







    share|improve this answer















    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
    .








    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 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






    • 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













    • @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





      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













    23














    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






    share|improve this answer





















    • 3





      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






    • 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 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
















    23














    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






    share|improve this answer





















    • 3





      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






    • 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 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














    23












    23








    23







    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






    share|improve this answer















    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







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Sep 1 '18 at 9:53

























    answered Oct 16 '12 at 21:46









    Ciro Santilli 新疆改造中心996ICU六四事件Ciro Santilli 新疆改造中心996ICU六四事件

    149k34560478




    149k34560478








    • 3





      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






    • 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 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














    • 3





      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






    • 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 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








    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











    21














    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.






    share|improve this answer





















    • 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. Only strtol is a viable solution.

      – AnT
      Aug 11 '11 at 6:55








    • 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
















    21














    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.






    share|improve this answer





















    • 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. Only strtol is a viable solution.

      – AnT
      Aug 11 '11 at 6:55








    • 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














    21












    21








    21







    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.






    share|improve this answer















    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.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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. Only strtol is a viable solution.

      – AnT
      Aug 11 '11 at 6:55








    • 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














    • 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. Only strtol is a viable solution.

      – AnT
      Aug 11 '11 at 6:55








    • 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








    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











    5














    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 =)






    share|improve this answer


























    • 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 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
















    5














    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 =)






    share|improve this answer


























    • 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 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














    5












    5








    5







    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 =)






    share|improve this answer















    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 =)







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 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 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 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 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











    2














    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;
    }





    share|improve this answer



















    • 1





      Doesn't handle overflow. Also, the parameter should be const char *.

      – Roland Illig
      Jan 21 '17 at 17:35








    • 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











    • @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
















    2














    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;
    }





    share|improve this answer



















    • 1





      Doesn't handle overflow. Also, the parameter should be const char *.

      – Roland Illig
      Jan 21 '17 at 17:35








    • 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











    • @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














    2












    2








    2







    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;
    }





    share|improve this answer













    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;
    }






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Oct 18 '16 at 19:26









    JacobJacob

    1488




    1488








    • 1





      Doesn't handle overflow. Also, the parameter should be const char *.

      – Roland Illig
      Jan 21 '17 at 17:35








    • 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











    • @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





      Doesn't handle overflow. Also, the parameter should be const char *.

      – Roland Illig
      Jan 21 '17 at 17:35








    • 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











    • @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











    0














    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






    share|improve this answer





















    • 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






    • 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
















    0














    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






    share|improve this answer





















    • 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






    • 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














    0












    0








    0







    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






    share|improve this answer















    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







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 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





      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





      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





      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











    0














    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;
    }





    share|improve this answer




























      0














      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;
      }





      share|improve this answer


























        0












        0








        0







        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;
        }





        share|improve this answer













        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;
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Sep 5 '15 at 15:36









        Khaled MohammadKhaled Mohammad

        1347




        1347























            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;
            }





            share|improve this answer
























            • 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
















            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;
            }





            share|improve this answer
























            • 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














            0












            0








            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;
            }





            share|improve this answer













            //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;
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 6 '15 at 13:05









            Aditya KumarAditya Kumar

            673




            673













            • 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

















            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











            -1














            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.






            share|improve this answer



















            • 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






            • 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











            • @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
















            -1














            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.






            share|improve this answer



















            • 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






            • 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











            • @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














            -1












            -1








            -1







            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.






            share|improve this answer













            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.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            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 the strto... family of functions. They are portable and significantly better.

              – chad
              Sep 2 '15 at 19:41






            • 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











            • @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





              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





              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






            • 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











            -3














            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...






            share|improve this answer



















            • 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
















            -3














            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...






            share|improve this answer



















            • 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














            -3












            -3








            -3







            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...






            share|improve this answer













            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...







            share|improve this answer












            share|improve this answer



            share|improve this answer










            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














            • 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











            -4














            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.






            share|improve this answer
























            • 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
















            -4














            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.






            share|improve this answer
























            • 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














            -4












            -4








            -4







            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.






            share|improve this answer













            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.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            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 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



















            • 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

















            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





            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?



            Popular posts from this blog

            Bressuire

            Vorschmack

            Quarantine