Reputation: 3
I have to find the frequency of digits {0,1,2,3,4,5,6,7,8,9} in a given string, I'm using atoi function to convert the character to an integer and I'm having problems with the atoi function when the input string is large (tried this with different test cases of varying length),
for example if the input string is
1v88886l256338ar0ekk
my code works properly and the answer is
1 1 1 2 0 1 2 0 5 0
where the 1st digit indicates the frequency of 0 and so on upto 9,
but if the input string is
9139f793308o0lo66h6vc13lgc697h0f6c32lu84445972k0o0l033od17c083yn5051d6j319hyo8j939n28d913015ns6zx5653x01211x12ch2526o65sg7xw6302141q9203s22l336319ll9yx4b597mr318a7943906750j4u152067nq83ne9f24thu96yd05173l47c803roxci45615f0w53i1sz913jj6za733l73tw6r66mq6p44sfhjr26h8e801z8zlcx2l1e65r2879xj3w3acv216196uq158o663y7oz2i5378v0v5w17762451t424352m23026r9o202i9785382o159e4gu1c8561157z5f1vqs5755465b8u728u956434mv944885li456628a994u7j5278m269n1pk8e46940q834h06il6h447888tr7ig72z10fe09k5g98h9bgt6z40v42s16pt6k3l3v45i83i01b9448g554741w766f2q7v31i085488h060e710p53076c6nm98pi946g8j2n6j8x29qa1ad48172y0u4818121p686bud89741201p54087u56g8scerv9pvhuo09re477zfb224i2c1325bj58jx4bk7b009f6446j5i95474p266i503r670n631x6940gwl71ejbx47imx576129248901765rnpu6l80084t0j1839f5y3409w2n403fu6ogw1170jmb6o5l520vg0703e0
upon reaching the end of the string the atoi function returns wrong values
for example,
my code uses atoi to convert char text to an integer and stores it into int num
at the beginning the function works fine,
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
.
.
.
and upon nearing the very end of the string the function returns
.
.
.
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
If I replace int num = atoi(&text)
with int num = text - '0'
my program works perfectly for all test cases,
so can someone please tell me what went wrong and whether I have used the function incorrectly. Please keep in mind I just want to know why atoi didn't work, hence I'm not looking for replacements for the function.
I've included the snippet of my code below
#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;
}
Thanks in advance for taking the time to read and answer my question
Upvotes: 0
Views: 532
Reputation: 44240
atoi()
since you are dealing with single characters, not with strings{}
braces by using break
and 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;
}
Upvotes: 1
Reputation: 1
Per the atoi()
documentation in the C standard:
The atoi, atol, and atoll functions convert the initial portion of the string pointed to by nptr to int, long int, and long long int representation, respectively.
Note the bolded part.
Given
char text;
this code invokes undefined behavior because the address passed to atoi()
is not that of a string:
int num = atoi(&text);
One fix would be:
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);
That ensures that a string (a nul-terminated series of char
) is passed to atoi()
.
Upvotes: 1