Reputation: 1
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
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
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
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
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