我试图从被解析的命令行中找出哪个函数最适合于将十进制、十六进制或八进制数字转换为最佳的int --事先不知道输入。
然后,目标是使用单个函数来识别不同类型的输入,并将其赋值为整数(int)值,然后可以这样使用:
./a.out 23 0xC4 070能打印
23
196 /*hexadecimal*/
56 /*octal*/我看到的唯一问题是解析,以查找十进制整数和八进制之间的差异。
附带的问题是,对于将字符串转换为整数以供使用,这是否稳定?
发布于 2014-04-04 14:48:10
哪个函数最好将十进制、十六进制或八进制数字转换为
int(?)
要将这样的文本转换为int,如果需要的话,建议在转换为int时使用附加测试的long strtol(const char *nptr, char **endptr, int base);。
使用0作为base评估早期字符在转向转换为基数10,16或8。
Convert text per:
Step 1: Optional whitespaces like `' '`, tab, `'\n'`, ... .
Step 2: Optional sign: `'-'` or `'+'`.
Step 3:
0x or 0X followed by hex digits--> hexadecimal
0 --> octal
else --> decimal 样本代码
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
int mystrtoi(const char *str) {
char *endptr;
errno = 0;
// v--- determine conversion base
long long_var = strtol(str, &endptr, 0);
// out of range , extra junk at end, no conversion at all
if (errno == ERANGE || *endptr != '\0' || str == endptr) {
Handle_Error();
}
// Needed when `int` and `long` have different ranges
#if LONG_MIN < INT_MIN || LONG_MAX > INT_MAX
if (long_var < INT_MIN || long_var > INT_MAX) {
errno = ERANGE;
Handle_Error();
}
#endif
return (int) long_var;
}atoi vs atol vs strtol vs strtoul vs sscanf .int
atoi()
非常简单。
Pro:转换为int。
支持:在C标准库中。
快。
对于超出范围的错误,未定义的行为。@chqrlie
既不处理十六进制也不处理八进制。
atol()
赞成:简单。
支持:在C标准库中。
快。
Con:转换为long,而不是可能大小不同的int。
对于超出范围的错误,未定义的行为。
既不处理十六进制也不处理八进制。
strtol()
赞成:简单。
支持:在C标准库中。
支持:很好的错误处理。
快。
Pro:能处理二进制文件。(基数2至36)
Con:转换为long,而不是可能大小不同的int。
strtoul()
赞成:简单。
支持:在C标准库中。
支持:很好的错误处理。
快。
Pro:能处理二进制文件。
-不抱怨负数
Con:转换为unsigned long,而不是可能大小不同的int。
sscanf(..., "%i", ...)
支持:在C标准库中。
Pro:转换为int。
-道路的复杂性
潜在的慢点。
Con: OK错误处理(溢出未定义)。
所有这些都受到/受益于locale设置。§7.22.1.4 6除"C“区域外,还可接受附加的特定地区主题序列形式。
额外贷项:
@Jonathan Leffler:针对ERANGE的errno测试,atoi()十进制测试,讨论errno多线程关注点.
@Marian速度问题。
@凯文图书馆包容性。
要转换short、signed char等,请考虑strto_subrange()。
发布于 2014-04-04 14:47:59
如果您关心错误条件,那么只需要考虑strtol()和strtoul() (或者<stdlib.h>中的strtoll()或strtoull(),或者<inttypes.h>中的strtoimax()或strtoumax() )。如果您不关心溢出的错误条件,则可以使用它们中的任何一个。atoi()、atol()和sscanf()都不能控制值是否溢出。此外,atoi()和atol()都不支持十六进制或八进制输入(因此实际上不能使用它们来满足您的需求)。
请注意,调用strtoX()函数并不完全简单。在调用它们之前,您必须将errno设置为0,并传递一个指针以获得结束位置,并仔细分析以了解发生了什么。请记住,来自这些函数的所有可能的返回值都是有效的输出,但其中一些可能也表示无效的输入-- errno和end指针帮助您区分所有输入。
如果需要在使用strtoll()读取值之后转换为strtoll(),则可以根据<limits.h> for int:INT_MIN和INT_MAX中定义的范围检查返回值的范围(存储在long long中)。
有关详细信息,请参阅我在以下网站的回答:strtol()。
请注意,这些函数都没有告诉您使用了哪种转换。你需要自己分析一下绳子。奇怪的注意:您是否知道C源中没有小数点0;当您编写0时,您正在写入一个八进制常数(因为它的第一个数字是0)。这件小事没有任何实际后果。
https://stackoverflow.com/questions/22865622
复制相似问题