我试图找出是否有一种在C中转换字符串为整数的替代方法。
在我的代码中,我经常使用以下模式。
char s[] = "45";
int num = atoi(s);
那么,有没有更好的办法呢?
我试图找出是否有一种在C中转换字符串为整数的替代方法。
在我的代码中,我经常使用以下模式。
char s[] = "45";
int num = atoi(s);
那么,有没有更好的办法呢?
当前回答
你可以编写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);
}
你也可以让它成为递归的,它可以折叠成3行。
其他回答
正如前面提到的,任何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位数字。
你可以编写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);
}
你也可以让它成为递归的,它可以折叠成3行。
不要使用来自ato…组。这些都坏了,几乎毫无用处。一个稍好的解决方案是使用sscanf,尽管它也不是完美的。
将字符串转换为整数,函数from strto…应该使用Group。在你的具体情况下,它将是strotol函数。
在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;
}
这可以帮助您将任何字符串转换为任何类型,如float, int, double…
在我看来,步行更好。我也喜欢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) 除了错误的处理可能有所不同。如果不能为 表示,行为是未定义的。