我试图找出是否有一种在C中转换字符串为整数的替代方法。
在我的代码中,我经常使用以下模式。
char s[] = "45";
int num = atoi(s);
那么,有没有更好的办法呢?
我试图找出是否有一种在C中转换字符串为整数的替代方法。
在我的代码中,我经常使用以下模式。
char s[] = "45";
int num = atoi(s);
那么,有没有更好的办法呢?
当前回答
不要使用来自ato…组。这些都坏了,几乎毫无用处。一个稍好的解决方案是使用sscanf,尽管它也不是完美的。
将字符串转换为整数,函数from strto…应该使用Group。在你的具体情况下,它将是strotol函数。
其他回答
在我看来,步行更好。我也喜欢strtonum,所以如果你有它就使用它(但记住它不方便携带):
long long
strtonum(const char *nptr, long long minval, long long maxval,
const char **errstr);
你可能还会对strtoumax和strtoimax感兴趣,它们是C99中的标准函数。例如,你可以说:
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) 除了错误的处理可能有所不同。如果不能为 表示,行为是未定义的。
你可以自己卷!
#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;
}
这样就可以做你想做的事情,而且不会杂乱。
正如前面提到的,任何C程序都不应该使用atoi函数族,因为它们没有任何错误处理。
strtol系列函数是100%等效的,但具有扩展功能:它具有错误处理功能,并且还支持十进制以外的其他进制,例如十六进制或二进制。因此正确的答案是:使用strtol (family)。
如果出于某种原因,您坚持自己手动推出这个函数,那么您应该尝试执行类似于strotol的操作,以防出现除可选符号和数字之外的其他符号。例如,我们想要转换大字符串中的数字是很常见的。
具有错误处理支持的简单版本可能如下所示。这段代码仅适用于十进制进制10的数字,但在其他方面表现类似于strtol,其可选指针设置为指向遇到的第一个无效符号(如果有的话)。还要注意,这段代码不处理溢出。
#include <ctype.h>
long my_strtol (char* restrict src, char** endptr)
{
long result=0;
long sign=1;
if(endptr != NULL)
{
/* if input is ok and endptr is provided,
it will point at the beginning of the string */
*endptr = src;
}
if(*src=='-')
{
sign = -1;
src++;
}
for(; *src!='\0'; src++)
{
if(!isdigit(*src)) // error handling
{
if(endptr != NULL)
{
*endptr = src;
}
break;
}
result = result*10 + *src - '0';
}
return result * sign;
}
例如,要处理溢出,可以添加代码来计数字符并检查它们是否超过10,假设长度为32位,最大可以是2147483647,10位数字。
这个函数会帮助你
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 - - 2.版本的html
是的,你可以直接存储整数:
int num = 45;
如果你必须解析一个字符串,atoi或strol将赢得“最短代码量”的比赛。