indranil majee
indranil majee

Reputation: 1

Given a string consisting of charachters, find the frequency of each digit

In the below code num1 is the output and the num2 is the expected output. What is the difference in (isdigit(s[i]) > 0) and (isdigit(s[i]) >= 0)?

int main()
{

    char s[1000];
    int num1[10] = { 0 }, num2[10], c;
    scanf("%s", s);
    int len = strlen(s);
    for (int i = 0; i <= len; i++) {
        if (isdigit(s[i]) >= 0) {
            c = (s[i]) - '0';
            num1[c] += 1;
        }
        if (isdigit(s[i]) > 0) {
            c = (s[i]) - '0';
            num2[c] += 1;
        }
    }
    for (int i = 0; i < 10; i++) {
        printf("%d ", num1[i]); //num1 is the output
        printf("%d ", num2[i]); //num2 is the expected output
    }

    return 0;
}

STDIN:8g614eggv7n388564l82nl6f35826hrzd533380b7870n4954497308f03wsx6zyr45025845zz55x7576631425l311cj4n9u29f4xje02l35t31m6me078bx421c24cocx83e438g88d069cc39bn6292033q055kk81m4f82798h7pt031mv530g4v7519h6g78z34p228f9z6067emv47e83uj805q805d572k18h077q6zzo22f35k22631l5j6n8fz0u583xkuu392613478x8823119241o6802910551sm8w9or6v78443c8wt63i3ft21d548p79h14i26k65qhbs79h65su27l1waz62m7l155bib1a2w401b8j7s2i719i68tr60492f685g7lx96i077775kq9436s6s6h81f827624583m894314vjvd41385ww0639e6xs8wzn6362a0029233j99097be0124408o90c861281jgu3168765af270z47e208bclp3845799e4p2710i231h

STDOUT: num1:32 32 39 37 34 34 40 37 46 30 num2:32 33 40 40 35 35 39 36 48 29

Upvotes: 0

Views: 116

Answers (4)

0___________
0___________

Reputation: 67638

You simply use the function the wrong way. isdigit returns a non zero value (it can be positive or negative) if the parameter is a digit.

There are some minor problems in the code as well.

int main(void)
{

    char s[1000];
    int num1[10] = { 0, }, c;

    scanf("%999s", s);
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++) {
        if (isdigit(s[i])) {
            num1[(s[i]) - '0']++;;
        }

    }
    for (size_t i = 0; i < 10; i++) {
        printf("%d ", num1[i]); //num1 is the output
    }

    return 0;
}

https://godbolt.org/z/h9qKqdvcK

Upvotes: 1

Alex Reynolds
Alex Reynolds

Reputation: 96967

The function isdigit has the following prototype:

int isdigit (int c);

This means the function takes an int as an argument, and returns an int as an answer.

If the value returned is zero, the argument is not a digit. If the value is not zero, the argument is a digit.

The test isdigit(s[i]) >= 0 is almost certainly not sensible or correct, because this can account for both some true and false conditions. The other test you use is incorrect, as well, as it can leave out some true results.

A more correct test for digits would be isdigit(s[i]) != 0, following the definition, to account for conditions where both negative and positive non-zero integers are returned from isdigit.

Upvotes: 2

alex01011
alex01011

Reputation: 1702

From the man page:

The isdigit() function shall return non-zero if c is a decimal digit; otherwise, they shall return 0.

Which means when you check if (isdigit(s[i]) >= 0), that will be true regardless s[i] is a digit or not. What you probably need is,

if (isdigit(s[i]) != 0) {
            c = (s[i]) - '0';
            num1[c] += 1;
        }

The other if block is wrong, num2[] array is uninitialized and will overflow in the event of a letter found , e.g 'a' - '0'.

You might also want to pass an unsigned char to functions like isdigit(), since anything not re presentable as unsigned char will result in Undefined Behavior.

The c argument is an int, the value of which the application shall ensure is a character representable as an unsigned char or equal to the value of the macro EOF. If the argument has any other value, the behavior is undefined.

Upvotes: 0

Andrew Henle
Andrew Henle

Reputation: 1

They're both wrong.

Per 7.4.1 Character classification functions, paragraph 1 of the C11 standard:

The functions in this subclause return nonzero (true) if and only if the value of the argument c conforms to that in the description of the function.

Values less than zero are still "true", so both implementations will miss digits where isdigit() happens to return a negative value - which is non-zero value albeit one that is less than zero.

But

if(isdigit(s[i]) >= 0)
{
    c = (s[i]) - '0';
    num1[c] += 1;
}

is more wrong in that it will return true for all non-digit characters where isdigit() returns zero.

To summarize:

The > implementation will miss some digits.

The >= implementation will miss some digits and count all non-digits as digits.

Upvotes: 3

Related Questions