The problem is that multi-byte data like UTF-8, stored in
char strings, produces negative values. The can't just throw those away.
The usual workaround for the nasty <ctype.h> functions is to cast the char value to unsigned char.
if (isalnum((unsigned char) str[i])) ..
type of thing. The <ctype.h> functions also have locale-specific behavior. What is an alphabetic character depends on locale. For instance various ISO Latin characters may be alphabetic. Unfortunately, those characters are also in the range of UTF-8 continuation bytes (128-255). If you blindly apply <ctype.h> on UTF-8 data in a program that has called setlocale() to establish some locale, you can get weird results.
If you intend to test for the ASCII alphabetic characters, and nothing else, no matter what the locale is set to, then your best bet is (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z').
The usual workaround for the nasty <ctype.h> functions is to cast the char value to unsigned char.
type of thing. The <ctype.h> functions also have locale-specific behavior. What is an alphabetic character depends on locale. For instance various ISO Latin characters may be alphabetic. Unfortunately, those characters are also in the range of UTF-8 continuation bytes (128-255). If you blindly apply <ctype.h> on UTF-8 data in a program that has called setlocale() to establish some locale, you can get weird results.If you intend to test for the ASCII alphabetic characters, and nothing else, no matter what the locale is set to, then your best bet is (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z').