isdigit() for characters greater than 127

  • Thread starter Alf P. Steinbach
  • Start date
A

Alf P. Steinbach

* James Gregory:
I read that the argument to isdigit() can be "an integer whose value is
representable as an unsigned char, or the value of the macro EOF.". This
seems to say that it should work for values greater than 127
Yes.


. And in
Linux + GCC, it does - values between 128 and 255 are false.

However, in Windows XP + GCC (at least some) values between 128 and 255
come out as true for isdigit. Someone suggested this may be because
Windows uses a different character set?

Perhaps.

The program

#include <iostream>
#include <iomanip> // setw
#include <cctype> // is_digit

int main()
{
using namespace std;

for( int i = 0; i <= UCHAR_MAX; ++i )
{
if( isdigit( i ) )
{
cout << setw( 3 ) << i << setw( 2 ) << char(i) << endl;
}
}
}

compiled with g++ 3.2.3, fails to reproduce your problem, giving

48 0
49 1
50 2
51 3
52 4
53 5
54 6
55 7
56 8
57 9

Why don't you check _which_ values and what the corresponding chars are
in the characters set used (Windows specific note: use chcp command if
this is a console program). And post the code and results. Always a
good idea to post the code -- we're not telepaths, you know... ;-)

So am I not supposed to use isdigit for non-ASCII values?

isdigit is not limited to ASCII.

What is the best alternative? Writing my own isdigit function?

What is the problem?
 
J

James Gregory

I read that the argument to isdigit() can be "an integer whose value is
representable as an unsigned char, or the value of the macro EOF.". This
seems to say that it should work for values greater than 127. And in
Linux + GCC, it does - values between 128 and 255 are false.

However, in Windows XP + GCC (at least some) values between 128 and 255
come out as true for isdigit. Someone suggested this may be because
Windows uses a different character set? So am I not supposed to use
isdigit for non-ASCII values? What is the best alternative? Writing my own
isdigit function?

Thanks,

James
 
J

John Harrison

James Gregory said:
I read that the argument to isdigit() can be "an integer whose value is
representable as an unsigned char, or the value of the macro EOF.". This
seems to say that it should work for values greater than 127. And in
Linux + GCC, it does - values between 128 and 255 are false.

However, in Windows XP + GCC (at least some) values between 128 and 255
come out as true for isdigit. Someone suggested this may be because
Windows uses a different character set? So am I not supposed to use
isdigit for non-ASCII values? What is the best alternative? Writing my own
isdigit function?

Perhaps you are writing this

char ch;
....
isdigit(ch);

when you should be writing this

char ch;
....
isdigit(static_cast<unsigned char>(ch));

The first alternative can pass a negative value to isdigit (because char is
signed) and that has undefined effects.

john
 
A

Alf P. Steinbach

* John Harrison:
Perhaps you are writing this

char ch;
...
isdigit(ch);

when you should be writing this

char ch;
...
isdigit(static_cast<unsigned char>(ch));

The first alternative can pass a negative value to isdigit (because char is
signed) and that has undefined effects.

Nitpick: "because char is signed" -> "because char may be a signed type,
depending on the implementation".
 
J

James Gregory

John Harrison said:
Perhaps you are writing this

char ch;
...
isdigit(ch);

when you should be writing this

char ch;
...
isdigit(static_cast<unsigned char>(ch));

The first alternative can pass a negative value to isdigit (because char is
signed) and that has undefined effects.

This was indeed my problem.

Thanks,

James
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top