您有 3 个选择:
atoi
如果您在性能关键代码中使用它,这可能是最快的,但它不会报告错误。如果字符串不以整数开头,则返回 0。如果字符串在整数后包含垃圾,则转换初始部分并忽略其余部分。如果数字太大而无法放入int
,则行为未指定。
sscanf
一些错误报告,并且您可以灵活地存储什么类型(签名/未签名版本char/short/int/long/long long/size_t/ptrdiff_t/intmax_t
)。
返回值是成功的转换次数,因此"%d"
如果字符串不是以整数开头,则扫描会返回 0。您可以使用"%d%n"
存储在另一个变量中读取的整数之后的第一个字符的索引,从而检查整个字符串是否已转换或之后是否有垃圾。然而,像 一样atoi
,整数溢出的行为是未指定的。
strtol
和家人
强大的错误报告,前提是您errno
在拨打电话之前设置为 0。返回值在溢出时指定errno
并将被设置。您可以选择从 2 到 36 的任何数字基数,或指定 0 作为基数以分别自动解释前导0x
以及0
十六进制和八进制。要转换为的类型选择是有符号/无符号版本的long/long long/intmax_t
.
如果您需要较小的类型,您始终可以将结果存储在临时long
或unsigned long
变量中并自己检查溢出。
由于这些函数采用指向指针参数的指针,因此您还可以免费获得指向转换后的整数之后的第一个字符的指针,因此您可以判断整个字符串是否为整数或在需要时解析字符串中的后续数据。
就个人而言,我会推荐这个strtol
家庭用于大多数目的。如果您正在做一些快速而肮脏的事情,atoi 可能会满足您的需求。
顺便说一句,有时我发现我需要解析不应该接受前导空格、符号等的数字。在这种情况下,滚动你自己的 for 循环非常容易,例如,
for (x=0; (unsigned)*s-'0'<10; s++)
x=10*x+(*s-'0');
或者您可以使用(为了稳健性):
if (isdigit(*s))
x=strtol(s, &s, 10);
else /* error */