字符串太长,没有给我正确的答案
string to long, not giving me the correct answer
我正在尝试将存储在 c 字符串中的数字转换为 long int。但我没有得到预期的输出:
char str[] = "987654321012345";
long int num ;
num = 0;
//num = atol(str);
num = strtol(str, (char **) NULL, 10);
printf("%ld", num);
输出:821493369
gcc 版本 4.4.7 20120313(红帽 4.4.7-16)
你能告诉我我在这里做错了什么吗?谢谢
您应该使用 long long
作为您号码的数据类型。
char str[] = "987654321012345";
long long num = strtoll(str, (char **)NULL, 10);
printf("%lld", num);
根据 C data type:
- Long signed integer type. Capable of containing at least the [−2,147,483,647, +2,147,483,647] range; thus, it is at least 32 bits in size.
- Long unsigned integer type. Capable of containing at least the [0, 4,294,967,295] range;
不够,所以你需要一个long long
或unsigned long long
并使用%lli
或%llu
除了使用 long long
,您还可以使用 stdint.h
中的 精确宽度 类型。例如,要保证 64 位 signed 数字,您可以使用 int64_t
类型。无论您做什么,都不要将 NULL
转换为char **
并且始终 验证您的转换。例如,
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main (void) {
char str[] = "987654321012345";
long num = 0;
errno = 0;
num = strtol (str, NULL, 10);
if (errno) { /* validate strtol conversion */
perror ("strtol conversion failed.");
return 1;
}
printf ("%ld\n", num);
return 0;
}
例子Use/Output
$ ./bin/strtoltst
987654321012345
您可以对转换进行额外的错误检查,但至少要确保在调用 strtol
或 strtoll
后未设置 errno
。
如果您想使用保证宽度类型,那么您可以进行以下更改:
...
#include <stdint.h>
...
int64_t num = 0;
...
num = strtoll (str, NULL, 10);
结果是一样的
“987654321012345”过大。
- Strol 正在输出 long 类型变量。
- 多头值为 –2,147,483,648 至 2,147,483,647。
尝试
char str[] = "987654321012345";
char *pEnd;
long long num;
num = 0;
num = strtoull(str,&pEnd, 10);
printf("%lld", num);
return 0;
- long long 而不是 long
strtoull 而不是 strtol
%lld 而不是 %ld
我可以重现并修复。
重现问题的代码
#include <stdio.h>
//#include <stdlib.h>
int main()
{
char str[] = "987654321012345";
long int num ;
char *ix;
num = 0;
//num = atol(str);
num = strtol(str, &ix, 10);
printf("%ld\n", num);
printf("%lu\n", sizeof(long));
return 0;
}
按预期提供:
821493369
8
编译警告后
warning: implicit declaration of strtoll
原因:由于 strtoll
未声明,假设为 return 和 int
,因此 long 值首先被截断为 int,然后再提升回 long。
修复:取消注释 #include <stdlib.h>
行...
结论:警告不能被忽略!
我正在尝试将存储在 c 字符串中的数字转换为 long int。但我没有得到预期的输出:
char str[] = "987654321012345";
long int num ;
num = 0;
//num = atol(str);
num = strtol(str, (char **) NULL, 10);
printf("%ld", num);
输出:821493369
gcc 版本 4.4.7 20120313(红帽 4.4.7-16) 你能告诉我我在这里做错了什么吗?谢谢
您应该使用 long long
作为您号码的数据类型。
char str[] = "987654321012345";
long long num = strtoll(str, (char **)NULL, 10);
printf("%lld", num);
根据 C data type:
- Long signed integer type. Capable of containing at least the [−2,147,483,647, +2,147,483,647] range; thus, it is at least 32 bits in size.
- Long unsigned integer type. Capable of containing at least the [0, 4,294,967,295] range;
不够,所以你需要一个long long
或unsigned long long
并使用%lli
或%llu
除了使用 long long
,您还可以使用 stdint.h
中的 精确宽度 类型。例如,要保证 64 位 signed 数字,您可以使用 int64_t
类型。无论您做什么,都不要将 NULL
转换为char **
并且始终 验证您的转换。例如,
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main (void) {
char str[] = "987654321012345";
long num = 0;
errno = 0;
num = strtol (str, NULL, 10);
if (errno) { /* validate strtol conversion */
perror ("strtol conversion failed.");
return 1;
}
printf ("%ld\n", num);
return 0;
}
例子Use/Output
$ ./bin/strtoltst
987654321012345
您可以对转换进行额外的错误检查,但至少要确保在调用 strtol
或 strtoll
后未设置 errno
。
如果您想使用保证宽度类型,那么您可以进行以下更改:
...
#include <stdint.h>
...
int64_t num = 0;
...
num = strtoll (str, NULL, 10);
结果是一样的
“987654321012345”过大。
- Strol 正在输出 long 类型变量。
- 多头值为 –2,147,483,648 至 2,147,483,647。
尝试
char str[] = "987654321012345";
char *pEnd;
long long num;
num = 0;
num = strtoull(str,&pEnd, 10);
printf("%lld", num);
return 0;
- long long 而不是 long
strtoull 而不是 strtol
%lld 而不是 %ld
我可以重现并修复。
重现问题的代码
#include <stdio.h>
//#include <stdlib.h>
int main()
{
char str[] = "987654321012345";
long int num ;
char *ix;
num = 0;
//num = atol(str);
num = strtol(str, &ix, 10);
printf("%ld\n", num);
printf("%lu\n", sizeof(long));
return 0;
}
按预期提供:
821493369
8
编译警告后
warning: implicit declaration of strtoll
原因:由于 strtoll
未声明,假设为 return 和 int
,因此 long 值首先被截断为 int,然后再提升回 long。
修复:取消注释 #include <stdlib.h>
行...
结论:警告不能被忽略!