您有 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 */