c - 作业,写一个将一串数字转换成整数的函数
问题描述
我知道我可以很容易地在 Internet 上找到该功能的代码页,但我想知道为什么在传递 10 位数组后,预期结果不像以前的那样。
#include <stdio.h>
int xstraylen(char *arr) {
int len;
for (len = 0; *(arr + len) != '\0'; len++) {
//printf("%c ", *(arr + len));
}
return len;
}
int str_into_int(char *str) {
int power = 10, len, number;
long int value = 0;
len = xstraylen(str);
printf("\n%d\n", len);
for (int index = 0; index < len; index++) {
number = (int)(*(str + index) - 48);
value += number;
value *= power;
printf("-%d- %d %d ", index, number, value);
}
value /= power;
return value;
}
int main() {
char *str = "1234567890";
int value;
value = str_into_int(str);
printf("\n\n%d", value);
return 0;
}
输出
10
-0- 1 10 -1- 2 120 -2- 3 1230 -3- 4 12340 -4- 5 123450 -5- 6 1234560 -6- 7 12345670 -7- 8 123456780 -8- 9 1234567890 -9- 0 -539222988
-53922298
解决方案
您的代码不适用于 10 位数字,因为value
在添加数字后总是在循环中乘以 10 并在最后除以。对于 10 位数字,最后一个乘法会在您的平台上导致算术溢出,其中两者都int
可能long
有 32 位。
您应该在添加数字之前乘以value
并删除最后的除法:
int str_into_int(char *str) {
int power = 10, len, number;
long int value = 0;
len = xstraylen(str);
printf("\n%d\n", len);
for (int index = 0; index < len; index++) {
value *= power;
number = (int)(*(str + index) - 48);
value += number;
printf("-%d- %d %ld ", index, number, value);
}
return value;
}
请注意,可以进一步简化和修改代码以处理更大的值并检测溢出:
#include <limits.h>
#include <stdio.h>
unsigned long long int str_into_int(const char *str) {
unsigned long long int value = 0;
for (int i = 0; str[i] >= '0' && str[i] <= '9'; i++) {
unsigned int digit = str[i] - '0';
if (value > ULLONG_MAX / 10 ||
(value == ULLONG_MAX / 10 && digit > ULLONG_MAX % 10)) {
printf("conversion exceeds range of unsigned long long\n");
return ULLONG_MAX;
}
value = value * 10 + digit;
}
return value;
}
void test(const char *str) {
printf("%s -> %llu\n", str, str_into_int(str));
}
int main() {
test("1234567890");
test("12345678901234567890");
test("18446744073709551615");
test("18446744073709551616");
test("123456789012345678901234567890");
return 0;
}
输出:
1234567890 -> 1234567890
12345678901234567890 -> 12345678901234567890
18446744073709551615 -> 18446744073709551615
conversion exceeds range of unsigned long long
18446744073709551616 -> 18446744073709551615
conversion exceeds range of unsigned long long
123456789012345678901234567890 -> 18446744073709551615
推荐阅读
- javascript - html2pdf:下载的pdf文本重叠并打破页面
- sql - 基于多表内连接更新列
- javascript - Appending a col div with jQuery in a for loop only gives me results on the first row
- ld - ld:链接为 elf i386 时找不到 -lc
- python-3.x - 查找和替换 xml 子标签文本的 Python 代码
- javascript - 即使在成功的承诺回调之后,组件道具也是空的 - 角度测试
- azure - 90 天后访问 Azure B2C 登录日志
- javascript - 您必须将组件传递给 connect 返回的函数。而是收到 {"propTypes":{}}
- php - 如何将变量从 foreach 循环发送到数组?
- c# - Visual Studio:弹出窗口以显示已实现的接口