我试图提出一种快速简单的方法:“从stdin获取一个字符串并将其转换为整数。如果不能,则假装我们得到零”。
这是一个Linux嵌入式系统,CPU和内存非常宝贵。性能很重要,准确性不那么重要。这应该能够每秒执行多次摄取。我最终将其转换为守护程序,并将最新的1024个值存储在数组中。
这是我使用atoi
的看法:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[] ) {
char *c = argv[1];
unsigned int i = 1; /* on atoi() failure, i = 0 */
if (i = atoi(c)) {
puts ("atoi() success");
}
else {
puts ("atoi() FAILED");
}
printf("argv[1] = %s\n", argv[1]);
printf(" i = %d\n", i);
}
一些测试运行/模糊测试:
# ./test_atoi 3
atoi() success
argv[1] = 3
i = 3
# ./test_atoi 99999999999999999999
atoi() success
argv[1] = 99999999999999999999
i = 2147483647
# ./test_atoi 3.14159
atoi() success
argv[1] = 3.14159
i = 3
# ./test_atoi $(echo -ne "\u2605")
atoi() FAILED
argv[1] = ★
i = 0
这将失败:
# ./test_atoi $(echo -e "\0")
Segmentation fault
我将添加一张NUL支票:
if (argv[1] == '\0') {
i = 0;
}
这样够了吗?我刚刚(严重)重新实现了
strtol
吗?我应该继续使用
strtol
吗?如果是,我应该检查的内容是否还不是strtol
?我真正真正关心的是不会因为输入错误而死亡。我可以很高兴地忍受转换带来的偶然垃圾。
编辑:
int i = 1
只是因为我想看看atoi()是否使其为0。贫民窟随时间推移的概况
编辑:我已经删除了打印语句,并在for循环中将从stdin读取的内容包装到atoi / strtol中。
# time seq 0 999888 | ./test_atoi
real 0m5.245s
user 0m5.870s
sys 0m0.030s
# time seq 0 999888 | ./test_atoi
real 0m5.230s
user 0m5.960s
sys 0m0.050s
# time seq 0 999888 | ./test_atoi
real 0m5.395s
user 0m5.920s
sys 0m0.080s
# time seq 0 999888 | ./test_strtol
real 0m5.332s
user 0m5.860s
sys 0m0.030s
# time seq 0 999888 | ./test_strtol
real 0m5.023s
user 0m5.790s
sys 0m0.060s
# time seq 0 999888 | ./test_strtol
real 0m5.286s
user 0m5.970s
sys 0m0.010s
好吧,这太疯狂了。我应该用自己的时间做一些更有成效的工作!
最佳答案
这是一个Linux嵌入式系统,CPU和内存非常宝贵。
是。嗯不如果您运行的是普通的linux,则内核将在几千个地方使用atoi
和反函数。除非您打算每秒调用数千次,否则您的单个数字解析器几乎不会产生任何影响。
我应该继续使用strtol吗?
由于上述原因:是。
如果是的话,我应该检查的内容还不是吗?
您应该检查strtol
的返回值。我真的不支持您的“不需要精确度”方法。这样的事情要么做对了,要么是灾难性的错误。
编辑你说:
不需要精度=我只关心值0-100
这意味着a)您只需要atoi
,而不是atol
/ strtol
;在那里,节省了CPU周期。接下来,您实际上是否需要将看起来像13.288
的字符串转换为整数,还是可以假设所有字符串的长度为1到3个字符?在这种情况下,为了获得原始性能,也许
inline unsigned char char2digit(const char *c) {
unsigned char v = *c - '0';
return (v<1 || v>9)? 0 : v;
}
inline signed char characters2number(const char *string)
{
size_t len = strnlen(string,4);
if(len < 1 || len > 3)
return -1;
signed char val = 0;
signed char power_of_ten = 1;
for(unsigned char idx = 1; idx <= len; ++idx)
{
signed char val += power_of_ten * char2digit(string + len - idx)
power_of_ten *= 10;
}
return val;
}
我的意思是,如果您在烤面包机上。否则
atoi
会退缩。您可能仍要检查strnlen
。