即使字符串转换成功,测试errno
也会返回一个指示错误的值:
#include <stdlib.h>
#include <sys/errno.h>
const char* numberString = "7";
char* endPtr;
errno = 0;
long number = strtol(numberString, &endPtr, 10);
NSLog(@"%ld", number);
if (errno) {
perror("string to integer conversion failed");
}
输出(在模拟器上,iOS 7)
$ 2014-05-22 09:27:32.954 Test[2144:60b] 7
$ string to integer conversion failed: No such process
设备上的行为类似。
strtol
man page在评论中说:
返回值
strtol(),strtoll(),strtoimax()和strtoq()函数返回转换结果, 除非该值会下溢或溢出。如果无法执行转换,则返回0并且 全局变量errno设置为EINVAL(最后一个功能不能在所有平台上移植)。如果 发生上溢或下溢,errno设置为ERANGE并且函数返回值被钳制 根据下表。
目前还不清楚这对iOS来说意味着什么。有什么见解吗?
事实证明,函数调用NSLog
确实设置了errno
。所以,@ Mat在他的回答和评论中都表示,“在调用一个不相关的函数(这里errno
)之后测试NSLog
时,所有的赌注都已关闭。
答案 0 :(得分:4)
如果无法执行转换,则返回0
你不是那种情况,7被退回。
如果发生上溢或下溢,...根据下表钳制返回值。
你也不是那种情况。
所以strtol
没有失败。检查errno
毫无意义。如果失败,记录在故障时设置errno
的功能将会这样做。当没有发生故障时,errno
的值是&#34;道德&#34;未定义。不要检查它。
strtol
是一个特例。 POSIX需要以下内容:
如果成功,这些功能不得更改
errno
的设置。
所以你的例子应该没问题。除非您在strtol
电话和errno
检查之间拨打电话。如果你100%确定该功能本身不会改变errno
,或者调用另一个可能设置它的功能,那么你在这个非常具体的情况下就可以了(记录的功能不是如果成功,改变errno
- 这不是常态)。显然,情况并非如此。 NSLog
很可能在某些时候使用某些系统调用,而那些(通常)不保证不会改变errno
。