如何解决为什么我不能在 c 中将字符串转换为 int
假设我们有一个字符数组input = "12345678987654321"
,为什么我不能用atoi()
把它转换成整数12345678987654321
?我试过了,它返回了一些我无法理解的数字。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char num[20];
scanf("%s\n",num);
printf("%d",atoi(num));
return 0;
}
解决方法
“12345678987654321”对于int
通常太大,并且atoi
不提供错误检测。
您可以使用 strto…
函数将字符串中的数字转换为整数类型。下面是一个使用 strtoimax
的示例,用于 C 实现支持的最宽有符号整数类型。还有其他类型的版本,例如 strtoll
的 long long
。
strto…
函数提供错误检查功能,因此您可以检测数字是否过大并将其报告给用户或以其他方式处理。
#include <ctype.h> // For isdigit and isspace.
#include <errno.h> // For errno.
#include <inttypes.h> // For stroimax and PRIdMAX.
#include <stdint.h> // For intmax_t.
#include <stdio.h> // For printf,fprintf,getchar,and ungetc.
#include <stdlib.h> // For exit.
int main(void)
{
// Read string.
char string[20];
int n = 0; // Number of characters read so far.
while (1)
{
int c = getchar();
// When we see the end of the input stream,leave the loop.
if (c == EOF)
break;
/* When we see a white-space character (including new-line),put it
back into the stream and leave the loop.
*/
if (isspace(c))
{
ungetc(c,stdin);
break;
}
/* If we see character that is not a space or a digit,complain,unless
it is the first character and is a sign,"+" or "-".
*/
if (!isdigit(c) && !(n == 0 && (c == '+' || c == '-')))
{
fprintf(stderr,"Error,non-digit seen: \"%c\".\n",c);
exit(EXIT_FAILURE);
}
// Record the digit.
string[n++] = c;
if (sizeof string / sizeof *string <= n)
{
fprintf(stderr,too many digits,can handle only %zu.\n",sizeof string / sizeof *string - 1);
/* ("sizeof *string" is one for ordinary "char" arrays,but
using it allows changing to wide character types if
desired.)
*/
exit(EXIT_FAILURE);
}
};
// Finish string with a null character.
string[n] = '\0';
// Attempt to convert string to an intmax_t.
char *end;
errno = 0; // Initialize error indicator.
intmax_t number = strtoimax(string,&end,0);
/* Test whether the string failed to match the form for a numeral,because
it was empty or was just a sign with no digits.
*/
if (end == string)
{
fprintf(stderr,numeral has no digits.\n");
exit(EXIT_FAILURE);
}
// Check for error.
if (errno != 0)
{
fprintf(stderr,number is too large for intmax_t.\n");
exit(EXIT_FAILURE);
}
/* Test whether the whole string was used in the conversion. It should have
been,considering we ensured each character was a digit,but a check
like this can be useful in other situations,where we are parsing a
numeral from a more general string.
*/
if (*end != 0)
{
fprintf(stderr,unexpected character in numeral,\"%c\".\n",*end);
exit(EXIT_FAILURE);
}
// Print the number.
printf("The number is %" PRIdMAX ".\n",number);
}
,
您得到奇怪输出的原因是输入的数字超出了 int
类型可表示的值范围。 atoi()
函数不一定执行错误检查,如果数字不能表示为 int
,它实际上具有未定义的行为。您应该改用 strtol()
。
您的程序还有另一个潜在的未定义行为:如果用户输入的字符超过 19 个,则 scanf("%s\n",num)
可能会写入超出 num
数组的末尾,这会带来可怕的后果。您应该编写 scanf("%19s",num)
并测试潜在转换错误的返回值。
这是修改后的版本:
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char num[20];
if (scanf("%19s",num) != 1) {
printf("no input\n");
return 1;
}
int c = getchar();
if (c != '\n' && c != EOF) {
printf("too many characters\n");
ungetc(c,stdin);
}
char *end;
errno = 0;
long value = strtol(num,10);
if (end == num) {
printf("input is not a number: %s",num);
} else {
if (errno != 0) {
printf("number %s is too large for type long\n",num);
} else
if (value < INT_MIN || value > INT_MAX) {
printf("number %ld is too large for type int\n",value);
} else {
printf("value is %d\n",(int)value);
}
if (*end != '\0') {
printf("extra characters after the number: %s",end);
}
}
return 0;
}
,
您输入的“12345678987654321” atoi 在 int 中,int 的范围从 -2,147,483,648 - 2,647
开始,因此为了修复它,请使用 atol()
l-long,这只是因为范围或如果您使用的是 32 位机器,那么您需要使用 long long int 即 atoll() 而不是 atol()
data size
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char num[20];
scanf("%s",num);
//printf("\n%s",num);
printf("\n%ld",atol(num)); //<- atoi(num) to atol(num)
return 0;
}
atol() 查看更多atoi()
、atol()
和 atoll()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。