在处理套打程序时用到TextOut,但TextOut无法自动换行,只好动手写代码,可是处理到汉字部分时卡住了,搜索网上判断汉字的帖子,都语焉不详,经过一下午的研究,终于整理出一个简单的教程。

其实判断汉字的代码很简单,简单到只有一行就可以了,但不理解汉字编码的基础,这一行代码却万万无法理解。

常用的字符编码有以下三种:

1、ASCII 只支持英文,全部为8位

2、DBCS  支持英文和中文,但中文需要两个字节(16位)

3、UNICODE 支持英文和中文,英文和中文都需要两个字节

ASCII是DOS时代的,无法支持中文。DBCS是Win9x支持的字符集。UNICODE是win2k和xp支持的字符集。

而汉字的编码目前有GB2312-1980和GB18030-2000,GB2312就是DBCS类型的汉字编码,GB18030就是UNICODE的汉字编码,当然GB18030兼容GB2312,也就是说GB18030也支持DBCS的字符处理方式。虽然GB18030是2000年后强制执行的国家标准,但目前使用最多的还是GB2312编码,而且GB2312也足够处理你所用到的汉字了。还有GBK编码是GB2312的增强版。

这里我仅支持GB2312。由于GB2312是中国大陆制定的标准,所以繁体中文并不在GB2312的编码中,如果你的程序需要支持繁体中文,则还需要处理Big5编码。其实也很简单。

下面说一下在C中如何处理GB2312编码的汉字。以VC6.0为例,如果声明变量的类型为wchar_t则是UNICODE编码,如果是char则是DBCS编码比如我的一个函数声明是:

void Justify (HDC hdc, PTSTR pText, RECT * prc, int iAlign)

其中的pText是PTSTR类型,PTSTR在WINNT.H中有两个定义(WINNT.H中的这段代码我删掉了中间无关的部分)

#ifdef  UNICODE

typedef LPWSTR PTSTR, LPTSTR;//如果是UNICODE编码,则定义PTSTR为LPWSTR类型

#else

typedef LPSTR PTSTR, LPTSTR;//如果是不是UNICODE编码,则定义PTSTR为LPSTR类型

#endif

LPSTR定义为CHAR的指针

LPSWSTR定义为WCHAR的指针

CHAR定义为char类型

WCHAR定义为wchar_t类型

而wchar_t定义为unsigned short类型,它是16位,两个字节,无符号短整数

是UNICODE还是非UNICODE取决于你的编译选项,如果在[工程]-[选项]-[C/C++]的[预处理程序定义]中填入了 _UNICODE,那么程序会用wchar_t指针来定义LPSTR,如果没有_UNICODE,那么程序会用char指针来定义LPSTR,这样带来的区别就是,你接受到的pText中的字节内容是不一样的,[i服了you]这个字串如果在没有定义_UNICODE的情况下,是8个字节,而在定义了 _UNICODE的情况下是12个字节。反映到程序中就是,如果没有定义_UNICODE,那么就要把英文字符当成1个字节来处理,而汉字字符的编码是采用GB2312编码规范来的;如果定义了_UNICODE,那么英文字符要当成2个字节来处理,而汉字字符的编码是采用UNICODE编码来的。举例来说,win98不采用UNICODE编码而采用的是DBCS编码,为了让我的程序既可以在XP下运行又可以在Win98下运行,我没有定义 _UNICODE。这样我的程序代码就要把字符串当成DBCS编码来处理,也就是英文字符是1个字节,中文字符是2个字节,中文编码采用GB2312编码。用Justify来说明:

我给pText传递来[你]这个汉字,那么pText应该有两个字节来存放[你]这个字,设置段点来读一下pText的内容。

void Justify (HDC hdc, PTSTR pText, RECT * prc, int iAlign)

{

static TCHAR szText[] = {TEXT ("你")} ;

pText=szText;

}

设断调试会发现*pText=-60,怎么会这样呢,原因是没有按unsigned char来转换*pText的值,修改代码如下:

void Justify (HDC hdc, PTSTR pText, RECT * prc, int iAlign)

{

static TCHAR szText[] = {TEXT ("你")} ;

unsigned char sqChar[20];//这个变量就是为了强制转换类型用的

pText=szText;

sqChar[0]=*pText;

sqChar[1]=*(pText+1);

}

这时下断查看sqChar[0]=196,sqChar[1]=227就对了,为什么呢,因为它和GB2312的编码是一样的。

GB2312-80编码的编码范围是高位0xa1-0xfe,低位是 0xa1-0xfe ,其中汉字范围为 0xb0a1 和 0xf7fe,如果只是简单地判断汉字,则只要查看高字节是否大于等于0xa1就可以了,还有就是,全角字符的高字节统统等于0xa3,所以很容易可以区别出全角字符来。

如果你希望你的程序能支持到GB18030,那么就去找GB18030的规范来看看。

网上有很多判断汉字的说法,你只要记住,你要支持的编码是哪个?GB2312、GBK、GB18030?每个编码有自己的编码范围或者规范,网上之所以有不同的说法,正是因为他们互相说的不是同一种编码方式。我这里说的是GB2312的编码,如果你的程序要编译成支持UNICODE的话,那么这段代码就要修改成对应UNICODE规范的代码了。

附简单的测试汉字、全角字符、英文的程序:

[c-sharp]  view plain copy print ?

//test.c

//源代码作者:夏克 sequh@126.com

//新建Win32 Application工程,把test.c加入,运行,试着修改szText的值,来观察代码效果

#include

intWINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, intiCmdShow)

{

staticTCHAR szText[] = {TEXT ("i服,了。uy")} ;

PTSTR pText;

inti;

unsigned charsqChar[20];

pText=szText;

while(*pText !='/0')

{

i=IsGB(pText);

switch(i)

{

case0:

pText++;

MessageBox (NULL, TEXT ("发现数字、英文字符或英文标点"), TEXT ("Hello"), 0);

break;

case1:

pText++;

pText++;

MessageBox (NULL, TEXT ("发现全角字符"), TEXT ("Hello"), 0);

break;

case2:

pText++;

pText++;

MessageBox (NULL, TEXT ("发现汉字"), TEXT ("Hello"), 0);

break;

}

}

return0 ;

}

intIsGB(PTSTR pText)

{

unsigned charsqChar[20];

sqChar[0]=*pText;

if(sqChar[0]>=0xa1)

if(sqChar[0]==0xa3)return1;//全角字符

elsereturn2;//汉字

else

return0;//英文、数字、英文标点

}

c语言字符是英文还是中文,c语言中判断中文还是英文字符相关推荐

  1. html网页模板中文乱码,Flash中出现中文乱码的解决办法

    在编辑flash文件中加载了非 Unicode 编码的外部txt文本文件时,有些中文就不能正常显示. 解决办法: 用鼠标右键单击舞台上的元件,从弹出的快捷菜单中选择"动作"选项,打 ...

  2. python支持中文吗_Python中使用中文

    这个问题曾在我初学Python的时候令我头疼不已,尤其是目前我们因为各种包的原因还只能使用2.x的版本.在3.x中字符编码已经统一用Unicode了. Python 默认支持的是ASCII字符,包含了 ...

  3. 计算机应用最普遍的汉字字符编码是什么,什么是计算机中应用最普遍的字符编码...

    什么是计算机中应用最普遍的字符编码 发布时间:2020-08-07 11:15:28 来源:亿速云 阅读:127 作者:Leah 什么是计算机中应用最普遍的字符编码?针对这个问题,这篇文章详细介绍了相 ...

  4. linux matlab 中文论坛,Linux中Matlab中文乱码问题解决方案

    Linux中Matlab中文乱码问题解决方案 由于Linux下Matlab的图形界面是用Java写的,所以只要搞定Java的中文显示就行了. 1.我Matlab2007a的JRE目录为:/opt/Ma ...

  5. python 十六进制转中文_Python列表中包含中文时输出十六进制转中文的小方法

    现象:列表中的中文打印出来后显示为十六进制>>> lt=['大神','zhzhgo'] >>> print lt ['\xb4\xf3\xc9\xf1', 'zhz ...

  6. vscode新建html中文乱码,vscode中html中文乱码 怎么办

    vscode中html中文乱码 怎么办?VSCode 中文乱码解决办法 文件 >> 首选项 >> 设置 搜索:"files.autoGuessEncoding&quo ...

  7. oracle中的中文排序,Oracle中的中文排序方式

    测试中文排序的版本: SQL> select * from v$version; BANNER ------------------------------------------------- ...

  8. linux的matplotlib中文异常,Linux中matplotlib 中文显示问题解决

    1.下载下载中文 arial unicode ms 字体到 /home 目录 2. 拷贝字体到 usr/share/fonts 下: sudo cp ~/arial\ unicode\ ms.ttf ...

  9. 在Java中中文需要用双引号吗_Java语言支持Unicode,自然支持中文,所以Java中可以使用中文的双引号、单引号、分号代替英文的双引号、单引号、分号。...

    A.Operated on patients.B.Played music to the patients.C.Cleaned the floo 试述厂商的要素使用原则. 用科学记数法记出的数7.04 ...

最新文章

  1. 对java集合类的认识——基础很重要
  2. mysql数据库项目例子_很实用的MySql数据库语句(项目中的例子)
  3. python创建项目包
  4. 10 个 GitHub 上最火的程序员简历项目,2021 金三银四必备!
  5. 语音特征提取: MFCC的理解
  6. Python说文解字_杂谈06
  7. Google电子地图基础及应用
  8. 64位的Mac OS X也有Windows.Forms了
  9. 牛客网【每日一题】7月30日题目精讲—Xor Path
  10. 机器学习--Lasso回归(LassoRegression)
  11. MYSQL - 存储过程学习笔记
  12. ios uiwindow弹窗_iOS-UIWindow详解
  13. oracle 每分钟执行,CSS_ORACLE JOB INTERVAL参数设置, 1:每分钟执行nb - phpStudy
  14. 控制台程序不显示dos窗口的方法
  15. oracle pdb与cdb区别,CDB与PDB的系统关系
  16. python中response是什么意思_python中的requests,response.text与response.content ,及其编码
  17. Android常见公有方法(隐藏虚拟按键/隐藏软键盘/获取屏幕宽高等)
  18. Kali2020详细的安装教程
  19. 功利主义穆勒思维导图_边沁与穆勒的功利主义思想之比较
  20. 影响计算机关键性能参数测试研究,【计算机病毒论文】谈灯光告警计算机测试系统设计(共3104字)...

热门文章

  1. 基于NodeJS的全栈式开发(基于NodeJS的前后端分离)【转】
  2. Unity3D 大型游戏 最后一站 源码 部分重点 整体框架(3)
  3. 瑞云服务云携手慧而特,引领餐饮设备服务创新升级
  4. 即将踏入工作,你对公司的若干职简称了解么?(CEO、CFO、CTO、CDO、CAO ...)
  5. 不定积分常用公式(详解版)
  6. html5语音读取文字_随时查,随时读,随时记--汉王e典扫描翻译笔A20T语音版
  7. 《Java并发编程之美》
  8. RecyclerView进阶使用(上拉加载)
  9. hue 3.1.2 启用kerberose认证
  10. 设计模式详解(四)--------建造者模式