将string转换为整数C

我试图找出是否有一个替代方法转换string为整数在C

我定期在我的代码中设置以下内容。

char s[] = "45"; int num = atoi(s); 

那么,有没有更好的方法或另一种方式?

有什么更好的国际海事组织。 我也喜欢strtonum ,所以使用它,如果你有它(但记住它不是便携式):

 long long strtonum(const char *nptr, long long minval, long long maxval, const char **errstr); 

编辑

你也可能对C99的标准functionstrtoumaxstrtoimax感兴趣。 例如,你可以说:

 uintmax_t num = strtoumax(s, NULL, 10); if (num == UINTMAX_MAX && errno == ERANGE) /* Could not convert. */ 

无论如何,远离atoi

呼叫atoi(str)应该相当于:

 (int) strtol(str, (char **)NULL, 10) 

除了错误的处理可能不同。 如果该值不能表示,行为是未定义的

C89基于strtol的解决scheme:

  • 没有不明确的行为( atoi家族可能会有这样的行为)
  • 整数比strtol更严格的定义(例如,没有领先的空白和尾随的垃圾字符)
  • 错误情况的分类(例如给用户提供有用的错误信息)
  • 一个“testing套件”
 #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] == '\0' || isspace((unsigned char) 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 != '\0') return STR2INT_INCONVERTIBLE; *out = l; return STR2INT_SUCCESS; } int main() { 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; } 

基于: https : //stackoverflow.com/a/6154614/895245

不要使用ato...组的function。 这些被打破,实际上是无用的。 稍微好一点的解决scheme是使用sscanf ,尽pipe它也不完美。

要将string转换为整数,应该使用来自strto... group的函数。 在你的具体情况下,这将是strtol函数。

你可以编写一些atoi()来获得乐趣:

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

你也可以使它recursion,至less可以在3行=)

只是想共享一个无符号长的解决scheme。

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

是的,你可以直接存储整数:

 int num = 45; 

如果你必须parsing一个string, atoistrol将赢得“最短的代码”比赛。

你可以随时推出自己的!

 #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: %d\n", my_atoi("34574")); printf("Returned number is: %d\n", my_atoi("-23")); return 0; } 

这将做你想要的没有混乱。

这个function会帮助你

 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 != '\0') { n++; temp++; } return strtoint_n(str, n); } 

参考: http : //amscata.blogspot.com/2013/09/strnumstr-version-2.html

好吧,我有同样的问题。我想出了这个解决scheme。它为我工作最好。我没有尝试atoi(),但没有为我工作好。所以这里是我的解决scheme:

 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; } 
 //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: %d\n", my_atoi("676987")); return 0; } 

在C ++中,你可以使用这样一个函数:

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

这可以帮助您将任何string转换为任何types,如float,int,double …