- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我试图从 stdlib.h
中找出函数 atoi()
。根据 K&R,它看起来像以下内容:
int atoi(char s[]) {
int n, i;
n = 0;
for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
n = 10 * n + (s[i] - '0');
return n;
}
据我所知,stdlib.h
中的atoi()
函数应该获取任何字符的字符串作为输入,并且只输出数字,如下所示:
代码 1:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("%i", atoi(" -123junk"));
printf("%i", atoi("0"));
printf("%i", atoi("junk")); // no conversion can be performed
printf("%i", atoi("2147483648")); // UB: out of range of int
}
输出:
-123
0
0
-2147483648
但是,在我的程序中,我尝试提供字符串作为输入并仅获取数字作为输出:
代码 2:
#include <stdio.h>
#include <stdlib.h>
int main() {
int c, i;
char s[i];
for (i = 0; (c = getchar()) != '\n'; ++i)
s[i] = c;
s[i] = '\n';
s[++i] = '\0';
printf("%i", atoi(s));
}
在机器上执行时:
pi@host:~/new$ cc new.c
pi@host:~/new$ a.out
21412421How it is
0
我得到的输出值不正确。
问题:
1) 根据代码 1,printf("%i", atoi("-123junk"))
,看起来函数 atoi()
可以接收字符串作为参数并返回单个整数,表示输入字符串中数字值的串联,不是吗?
2) stdlib.h
中的atoi()
返回什么?
3) 如何修复代码 2 中的函数 main()
,以便从 stdin
获取字符,写入数组,调用函数 atoi()
,提供数组作为参数,按字面意思接收输出中的数字?
4) 根据函数 atoi()
的 K&R 示例,“表达式 (s[i] - '0')
是字符的数值存储在s[i]
”,但是,为什么我们需要添加10 * n
部分,而且将n
分配给0
在它之前,因为 n * 0 = 0
,因此,n * 10 = 0
,这意味着 n * 10
在赋值语句 n = 10 * n + (s[i] - '0') 中始终为零;
,因此,我们为什么需要它?
5) 如果 atoi() 返回一个整数,printf("%i", atoi("-123junk"));
的结果如何返回一个数字字符串 -123
?换句话说,我是否理解正确:函数 atoi()
在函数 printf()
中被调用,"-123junk"
为一个论点。函数 atoi()
返回整数,只有一个整数,类似于 n = 10 * n + (s[i] - '0');
比,如何可以在-123
展开吗??
最佳答案
Q1) 您的 atoi()
版本太简单了,标准版本忽略前导空白字符并处理数字前的可选符号。 atoi("-123junk")
的计算结果应为 -123
。
Q2) atoi
是一个用原型(prototype)int atoi(const char *s);
定义的标准函数;它返回一个整数。
Q3) 代码2
有几个错误:
char
数组s
的大小指定为未初始化的i
。你应该用一个相当大的值来定义数组,比如 64
,EOF
以停止循环,以防在没有换行符的情况下遇到文件结尾。修改后的版本:
#include <stdio.h>
#include <stdlib.h>
int main() {
char s[64];
size_t i;
int c;
for (i = 0; i < sizeof(s) - 1 && (c = getchar()) != EOF;) {
s[i++] = c;
if (c == '\n')
break;
}
s[i] = '\0';
printf("%i", atoi(s));
return 0;
}
Q4) 表达式 n = 10 * n + (s[i] - '0')
为字符串中找到的每个新数字求值。只要没有遇到非零数字,将当前值乘以 10 确实有点低效,但是这样写函数很简单。
为了避免这些无用的乘法,这里有一个替代方案:
int atoi(const char *s) {
int n = 0;
size_t i = 0;
while (s[i] == '0')
i++;
if (s[i] >= '1' && s[i] <= '9') {
n = s[i++] - '0';
while (s[i] >= '0' && s[i] <= '9')
n = 10 * n + (s[i++] - '0');
}
return n;
}
但是这个函数比较麻烦,实际上可能不如简单版本有效。在您的系统上尝试和基准测试。
为了完整起见,这里是一个完整的可移植版本,使用 ctype.h>
处理可选的初始空白和可选的符号。它还通过定义的行为处理溢出,尽管 atoi()
的标准版本不需要这样做。
#include <limits.h>
#include <stdio.h>
int atoi(const char *s) {
int n = 0, d;
/* skip optional initial white space */
while (isspace((unsigned char)*s))
s++;
if (*s == '-') {
/* convert negative number */
s++;
while (isdigit((unsigned char)*s)) {
d = (*s++ - '0');
/* check for potential arithmetic overflow */
if (n < INT_MIN / 10 || (n == INT_MIN / 10 && -d < INT_MIN % 10)) {
n = INT_MIN;
break;
}
n = n * 10 - d;
}
} else {
/* ignore optional positive sign */
if (*s == '+')
s++;
while (isdigit((unsigned char)*s)) {
d = (*s++ - '0');
/* check for potential arithmetic overflow */
if (n > INT_MAX / 10 || (n == INT_MAX / 10 && d > INT_MAX % 10)) {
n = INT_MAX;
break;
}
n = n * 10 + d;
}
}
return n;
}
int main(int argc, char *argv[]) {
int i, n;
for (i = 1; i < argc; i++) {
n = atoi(argv[i]);
printf("\"%s\" -> %d\n", argv[i], n);
}
return 0;
}
关于c - "string of digits into its numeric equivalent"示例无法根据 K&R 正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54225045/
我需要一个正则表达式,它只会选择那些不以 .png 或 .css 等特定扩展名结尾的 URL 字符串。 我测试了以下内容: 1)这个使用负回顾: (? SetHandler "proxy:un
我似乎无法确切地掌握名称的等效性。我很确定我的结构已经下降。我的教授给出的一个例子是: Type TI=integer Type TTI=TI a=integer b=TTI f= ref
我最近为问题“A Regex that will never be matched by anything ”( my answer here ,请参阅更多信息)计时了一堆正则表达式。 然而,在我测试
Clojure 为 提供方法懒惰评估 (无限)序列中的值。有了这个,值只会在它们被实际消耗时计算。 一个重复元素的无限序列示例: (take 3 (repeat "Hello StackOverflo
如果我使用文本文件在 Solr/Lucene 中定义同义词,如下所示: foo, bar, goo abc, bar, xyz 字bar在两条线上。 这是否意味着 Solr 将所有术语都视为同义词,因
在 Xcode 中,当您设置键盘快捷键时,有一个很好的控件可以帮助您: 我觉得我可以通过扩展 NSTextField 来重现它,但我也觉得这可能是其他人以前做过的事情。我做了一些搜索,但没有找到任何结
我对汇编语言有点陌生,很难理解术语“字节等效”。 它用于以下上下文:- MOV 指令有时会引起歧义。例如,查看以下语句: MOV EBX, [MY_TABLE] ; Effective Addre
这是一个“软性问题”,因此,如果此发布地点不合适,请告诉我。 本质上,我想知道如何谈论在某种意义上“等效”而在另一些意义上“不同”的算法。 这是一个玩具示例。假设我们得到了一个长度为list的数字n的
我(在 Protege 中)定义了一个 Missing 类,它相当于 ((not (atHome value 30)) and (not (atWork value 30)))and (not (on
我正在处理一个烦人的数据库,其中一个字段包含真正应该存储在两个单独字段中的内容。因此该列存储的内容类似于“第一个字符串~@~第二个字符串”,其中“~@~”是分隔符。 (再说一次,我没有设计这个,我只是
在 Django 中,这两个是等价的吗? Cars.objects.exclude(brand='mercedes').exclude(year__lte=2000) 和 Cars.objects.e
此代码行选择任何类名不是“id”和“quantity”的 div 内的所有子输入:: $("div.item > div:not(.id,.quantity) > :input").live("key
在 Vue 1.x 中,我使用以下指令直接选择一个节点。 然后: this.$els.visibleColumns 是否有 Vue 2.x 方法来做到这一点? 最佳答案 当然,所以它已被 ref/$
我在underscore.js源码中看到了这段代码: if ((!a && b) || (a && !b)) return false; 这是否等同于以下内容? if (a ^ b) return f
我需要一些关于批处理文件中 grep -v Wildcard 和 grep -o 的等效代码的帮助。 这是我在 shell 中的代码。 result=`mysqlshow --user=$dbUser
我试图在 SQL 中找到等同于 IN\NOT 的 ElasticSearch 查询。 我知道我们可以使用带有多个 OR 的 QueryString 查询来获得相同的答案,但最终会得到很多 OR。 谁能
On a separate post , 我在帮忙George Edwards使用 BLE API 分解一些代码. 我很确定我发布的代码(使用分解模板)与原始代码相同。但是当 George 将它发送到
是否有办法“模仿”background-size:cover; 的行为? (参见 http://www.w3schools.com/cssref/playit.asp?filename=playcss
我正在使用 Qt。我需要直接向我的打印机写入一些文本。在 Windows 上,我可以使用 winapi OpenPrinter 和 WritePrinter 执行此操作,但我需要此代码才能在 linu
我搜索过并使用过 UIDevice.currentDevice().instancesRespondToSelector(Selector("userInterfaceIdiom")) 但对我不起作用
我是一名优秀的程序员,十分优秀!