本文只针对对字母数字等判断部分。
ASCII码
首先需要了解基础知识ASCII码,如下:
以真实的值代表设定的含义,这是一种编码方式。只针对编码前0~128部分
字符分类
大概分成几种类型:
- 字母(大小字母)
- 数字
- 控制字符
- 可打印字符
- 空白字符
那么我们可将0到128定义成一个数组形式的表,用来查表代表字符是哪种类型。
#define _CTYPE_NUM_CHARS 128
const uint8_t _C_ctype_[1 + _CTYPE_NUM_CHARS] = {
0,
_C, _C, _C, _C, _C, _C, _C, _C,
_C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C,
_C, _C, _C, _C, _C, _C, _C, _C,
_C, _C, _C, _C, _C, _C, _C, _C,
_S|_B, _P, _P, _P, _P, _P, _P, _P,
_P, _P, _P, _P, _P, _P, _P, _P,
_N, _N, _N, _N, _N, _N, _N, _N,
_N, _N, _P, _P, _P, _P, _P, _P,
_P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U,
_U, _U, _U, _U, _U, _U, _U, _U,
_U, _U, _U, _U, _U, _U, _U, _U,
_U, _U, _U, _P, _P, _P, _P, _P,
_P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L,
_L, _L, _L, _L, _L, _L, _L, _L,
_L, _L, _L, _L, _L, _L, _L, _L,
_L, _L, _L, _P, _P, _P, _P, _C
};
const unsigned char *_ctype_ = _C_ctype_;
第一个是0,使用时候偏移量+1即可,这里不影响。0到127为128个数,再加开始的0,为 1 + _CTYPE_NUM_CHARS
上面分组类型分为字母数字用标志位形式定义,填入数组中,比如数组里面与ASCII对应,数组角标填入可直接输出字符的类型,是字母还是数字。
分类的字母数字等,又可以通过位形式包含
例如将二进制111(十进制7)设定为英文字母大写标志,那可打印标志设置为1,标志&成立,则这个字符是可以进行打印。
举例实现
下面进行举例实现库函数,希望大家可以举一反三。
判断字符是否是字母或者数字
int isalnum(int c)
{
/*- 输入值非-1时查表法与数字和字母对比结果返回 */
return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_U | _L | _N)));
}
ctype +1是将开始0偏移掉,将字符填入数组以角标方式直接获取到该字符的类型,不为0时是成立。
判断字符是否是ASCII码
int lib_isascii(int c)
{
return ((c >= 0x00 && c <= 0x7f) ? 1 : 0);/* 在0~127之间为ASCII码 */
}