猿问

sscanf或atoi将字符串转换为整数有什么区别?

gcc 4.4.4 c89


将字符串转换为整数值更好。


我尝试了2种不同的方法atoi和sscanf。两者都按预期工作。


char digits[3] = "34";

int device_num = 0;


if(sscanf(digits, "%d", &device_num) == EOF) {

    fprintf(stderr, "WARNING: Incorrect value for device\n");

    return FALSE;

}

或使用atoi


device_num = atoi(digits);

我以为sscanf会更好,因为您可以检查错误。但是,atoi不会进行任何检查。


九州编程
浏览 1057回答 3
3回答

海绵宝宝撒

*scanf()函数系列返回转换后的值的数量。因此,您应该检查以确保sscanf()返回1。 EOF因“输入失败”而ssacnf()返回,这意味着将永不返回EOF。对于sscanf(),函数必须解析格式字符串,然后解码整数。 atoi()没有那笔开销。两者都遭受以下问题:超出范围的值会导致未定义的行为。您应该使用strtol()或strtoul()函数,它们可以提供更好的错误检测和检查。他们还会让您知道整个字符串是否已被消耗。如果需要int,可以随时使用strtol(),然后检查返回的值以查看它是否位于INT_MIN和之间INT_MAX。

红颜莎娜

如果不用担心无效的字符串输入或范围问题,请使用最简单的方法: atoi()否则,具有最佳错误/范围检测的方法既不是也不atoi()是sscanf()。 这很好的答案都准备好了细节上缺乏错误检查atoi()和一些错误检查sscanf()。strtol()是将字符串转换为的最严格的函数int。但这仅仅是一个开始。下面是详细的示例,以显示正确的用法,并在被接受后给出此答案的原因。// Over-simplified useint strtoi(const char *nptr) {&nbsp; int i = (int) strtol(nptr, (char **)NULL, 10);&nbsp; return i;&nbsp;}就像这样atoi(),忽略了使用的错误检测功能strtol()。要充分利用strtol(),需要考虑多种功能:检测到没有转换:示例:"xyz"或""或"--0"?在这些情况下,endptr将匹配nptr。char *endptr;int i = (int)strtol(nptr, &endptr, 10);if (nptr == endptr) return FAIL_NO_CONVERT;整个字符串应该转换还是仅转换开头部分:"123xyz"可以吗?char *endptr;int i = (int)strtol(nptr, &endptr, 10);if (*endptr != '\0') return FAIL_EXTRA_JUNK;检测是否值这么大,结果不表示为一个long样"999999999999999999999999999999"。errno = 0;long L = strtol(nptr, &endptr, 10);if (errno == ERANGE) return FAIL_OVERFLOW;检测该值是否在than的范围之外int,但不是long。如果int和long具有相同的范围,则不需要此测试。long L = strtol(nptr, &endptr, 10);if (L < INT_MIN || L > INT_MAX) return FAIL_INT_OVERFLOW;某些实现超出了C标准,并errno出于其他原因进行了设置,例如在未执行转换的情况下将errno设置为EINVAL或EINVAL Base参数的值无效。。测试这些errno值的最佳时间取决于实现。全部放在一起:(根据您的需要进行调整)#include <errno.h>#include <stdlib.h>int strtoi(const char *nptr, int *error_code) {&nbsp; char *endptr;&nbsp; errno = 0;&nbsp; long i = strtol(nptr, &endptr, 10);&nbsp; #if LONG_MIN < INT_MIN || LONG_MAX > INT_MAX&nbsp; if (errno == ERANGE || i > INT_MAX || i < INT_MIN) {&nbsp; &nbsp; errno = ERANGE;&nbsp; &nbsp; i = i > 0 : INT_MAX : INT_MIN;&nbsp; &nbsp; *error_code = FAIL_INT_OVERFLOW;&nbsp; }&nbsp; #else&nbsp; if (errno == ERANGE) {&nbsp; &nbsp; *error_code = FAIL_OVERFLOW;&nbsp; }&nbsp; #endif&nbsp; else if (endptr == nptr) {&nbsp; &nbsp; *error_code = FAIL_NO_CONVERT;&nbsp; } else if (*endptr != '\0') {&nbsp; &nbsp; *error_code = FAIL_EXTRA_JUNK;&nbsp; } else if (errno) {&nbsp; &nbsp; *error_code = FAIL_IMPLEMENTATION_REASON;&nbsp; }&nbsp; return (int) i;}注意:提到的所有功能都允许前导空格,可选的前导符号字符,并受语言环境更改的影响。需要更多代码才能进行更严格的转换。注意:非OP标题更改偏重于重点。此答案更好地适用于原始标题“将字符串转换为整数sscanf或atoi”
随时随地看视频慕课网APP
我要回答