You should be using unsigned char
to manage characters. For example, fgetc
returns a “character as an unsigned char
converted to an int
” (C 2018 7.21.7.1). Use char
can result in negative values and undefined behavior, as explained below.
7.4 1 defines the behavior of the <ctype.h>
functions only for arguments whose value is representable as an unsigned char
or EOF
:
In all cases the argument is an int
, the value of which shall be representable as an unsigned char
or shall equal the value of the macro EOF
. If the argument has any other value, the behavior is undefined.
Thus, if you have a char
with a negative value, and you pass it to one of the <ctype.h>
functions, that value is not representable as an unsigned char
. And it is generally not EOF
either. The negative char
value will be implicitly converted to an int
by the function call, but the value will remain negative. So the behavior would not be defined by the C standard.
Per 6.2.5 3, all members of the basic execution character set have non-negative values:
If a member of the basic execution character set is stored in a char
object, its value is guaranteed to be nonnegative.
Per 5.2.1 3, The basic execution character set includes at least the Latin alphabet in uppercase and lowercase, the ten digits, space, horizontal tab, vertical tab, form feed, alert, backspace, carriage return, new line, and these characters:
!"#%&’()*+,-./: ;?[\]^_{|}~
So, if your string has any other character, it could have a negative value. Then, the behavior of the <ctype.h>
functions is not defined by the C standard.