我必须找到给定字符串中数字{0,1,2,3,4,5,6,7,8,9}的频率,我正在使用 atoi 函数将该字符转换为整数,并且当输入字符串很大时(在不同长度的不同测试用例中尝试过),我在 atoi 函数中遇到了问题,
例如,如果输入字符串是
1v88886l256338ar0ekk
我的代码正常工作,答案是
1 1 1 2 0 1 2 0 5 0
其中第一个数字表示频率为0,依此类推,直到9,
但如果输入字符串为
9139f793308o0lo66h6vc13lgc697h0f6c32lu84445972k0o0l033od17c083yn5051d6j319hyo8j939n28d913015ns6zx5653x01211x12ch2526o65sg7xw6302141q9203s22l336319ll9yx4b597mr318a7943906750j4u152067nq83ne9f24thu96yd05173l47c803roxci45615f0w53i1sz913jj6za733l73tw6r66mq6p44sfhjr26h8e801z8zlcx2l1e65r2879xj3w3acv216196uq158o663y7oz2i5378v0v5w17762451t424352m23026r9o202i9785382o159e4gu1c8561157z5f1vqs5755465b8u728u956434mv944885li456628a994u7j5278m269n1pk8e46940q834h06il6h447888tr7ig72z10fe09k5g98h9bgt6z40v42s16pt6k3l3v45i83i01b9448g554741w766f2q7v31i085488h060e710p53076c6nm98pi946g8j2n6j8x29qa1ad48172y0u4818121p686bud89741201p54087u56g8scerv9pvhuo09re477zfb224i2c1325bj58jx4bk7b009f6446j5i95474p266i503r670n631x6940gwl71ejbx47imx576129248901765rnpu6l80084t0j1839f5y3409w2n403fu6ogw1170jmb6o5l520vg0703e0
在到达字符串末尾时, atoi 函数将返回错误的值
例如,
我的代码使用 atoi 将字符文本转换为整数并将其存储到 int num
一开始该功能运行正常,
text is 9 num is 9
text is 1 num is 1
text is 3 num is 3
text is 9 num is 9
text is 7 num is 7
text is 9 num is 9
text is 3 num is 3
text is 3 num is 3
text is 0 num is 0
text is 8 num is 8
text is 0 num is 0
.
.
.
并且在接近字符串的最末尾时,函数将返回
.
.
.
text is 2 num is 2
text is 4 num is 4
text is 0 num is 0
text is 3 num is 30
text is 6 num is 60
text is 1 num is 10
text is 1 num is 10
text is 7 num is 70
text is 0 num is 0
text is 6 num is 61
text is 5 num is 51
text is 5 num is 51
text is 2 num is 21
text is 0 num is 1
text is 7 num is 71
text is 0 num is 1
text is 0 num is 1
text is 3 num is 31
如果我将int num = atoi(&text)
替换为int num = text - '0'
,则我的程序可以在所有测试用例中正常运行,
所以有人可以告诉我哪里出了问题以及我是否使用了错误的功能。 请记住,我只是想知道为什么 atoi 无法正常工作,因此我没有在寻找该功能的替代产品。
我在下面包含了我的代码段
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
int main() {
int arr[10] = {0};
char text;
text = getchar();
while(text != EOF)
{
if(isdigit(text))
{
printf("text is %c ",text);
int num = atoi(&text);
printf("num is %d\n ",num);
for(int i =0; i<10;i++)
{
if(num==i)
{
arr[i]++;
//printf("arr[%d] is %d\n", i,arr[i]);
break;
}
}
}
text = getchar();
}
for(int i=0; i<10;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
预先感谢您抽出宝贵的时间阅读和回答我的问题
答案 0 :(得分:1)
每the atoi()
documentation in the C standard:
atoi,atol和atoll函数分别将nptr指向的字符串的初始部分转换为int,long int和long long int表示形式。
请注意加粗的部分。
给予
char text;
此代码调用未定义的行为,因为传递给atoi()
的地址不是字符串的地址:
int num = atoi(&text);
一个解决方法是:
char text[2];
text[1] = '\0';
// getchar() returns int, not char, in order
// to handle EOF properly
int input = getchar();
while(input != EOF)
{
text[0] = input;
if(isdigit(text[0]))
{
printf("text is %s ",text);
int num = atoi(text);
这确保将字符串(以char
结束的无符号序列)传递给atoi()
。
答案 1 :(得分:1)
atoi()
,因为您是在处理单个字符,而不是字符串{}
和break
来避免使用许多continue
大括号#include <stdio.h>
#include <ctype.h>
int main() {
int arr[10] = {0};
int text, num;
while(1) {
text = getchar();
if (text == EOF) break;
if (!isdigit(text)) continue;
printf("text is %c ", text);
num = text - '0'
printf("num is %d\n ",num);
arr[num]++;
//printf("arr[%d] is %d\n", num, arr[num]);
}
for(int i=0; i<10;i++)
{
printf("%d ",arr[i]);
}
return 0;
}