Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1009022
  • 博文数量: 238
  • 博客积分: 2842
  • 博客等级: 少校
  • 技术积分: 2765
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-16 00:20
个人简介

stdlf

文章分类

全部博文(238)

文章存档

2013年(6)

2012年(13)

2011年(82)

2010年(89)

2009年(48)

我的朋友

分类:

2010-03-19 10:37:14

有很多这样的编者,他们永远不会在一本书中详尽地叙述一个看起来非常简单的例子。因为这样看来象是在浪费纸张。但是初学者永远是有的,在碰到困难的时候,他们很需要得到耐心的指导和帮助,而事实上他们所看到的都是些“高层次”的内容。每个编者都是从初学者开始的,但他们开始编书的时候,往往不屑于那些细节的问题,这是令读者很苦恼的。

汉字是怎样写到屏幕上来的,中断能用来干什么,还有怎样让你的程序支持鼠标的操作,在此我们开辟了系列讲座:汉字的处理技术、中断的处理技术、鼠标的处理技术,内容由浅至深,环环相扣,很符合初学者的特点。每一章节都提供有很好的例程,并且附上程序的真实运行结果。建议读者要读懂它们,并且能够“临摹”出一些类似的程序来。

关于本文的读者对象,要求能熟悉C语言的基本语法以及关于文件的基本操作,还有一点UCDOS的操作。“程序永远没有结束的时候”。希望读者朋友们能相互切磋,共同提高。

汉字的处理技术(一)

许多读者朋友学会了基本的C语言编程以后,就开始对汉字技术产生了兴趣。本篇分别从中文状态、西文状态、文本方式、图形方式四种情形进行汉字处理的介绍。

一、中文状态下的汉字处理

1.第一个汉字处理程序

学习C语言首先都是从著名的“Hello world!”程序起步,它的程序清单如下:

/*test01l. c*/

main( )

{

printf("Helloworld! \n");

}

以下是它的汉化版:

/*test02. c/

main()

{

printf("你好,世界!\n");

}

这个程序是合法的,而且非常简单,但编辑、编译工作常常令初学者感到迷惑。实际上,这些工作必须按以下步骤进行:

①     运行UCDOS(或其他汉字系统);

②     运行TC;

③     编辑test02. c;

④     编译、运行。

2. UCDOS为我们干了什么

编译运行以下程序:

/*test03.c/

main()

{

printf("%c%c! \n" 0xc5 0xde);

}

image004[1,304字节]

我们在UCDOS下,再运行同样的程序,它将得到另一种结果:

image006[1,358字节]

原先看似文静的test03. c变得如此面目可憎。

UCDOS到底为我们干了什么?我们通常所说的一个汉字占两个字节究竟是什么含义?汉字的机内码又是什么意思?下面就详细谈谈它。

众所周知,一个ASCII字符占一个字节,它的数值从0到255。UCDOS作为一个操作系统,它应该允许用户通过ASCII码来调用相应的字符。那么这样一来,汉字字符将如何与ASCII字符区别开来呢?

实际上,仔细观察ASCII字符表,从第161个字符开始,后面的字符并不经常为用户所使用。UCDOS充分利用这一特性,将161-255之间的数值空间作为汉字的标识码。既然255-161 = 94不能满足汉字容量的要求,就将每两个字符并在一块(即一个汉字占两个字节),显然,94* 94 =8836基本上已经满足了常用汉字个数的要求。

这样,在UCDOS环境下,对于字符的处理就有所不同。如果连续两个码值都大于160的话,那么则认为是汉字;否则都认为是ASCII码。

以上的描述可以用程序test04.c来模拟:

/*test04.c/

#include

main()

{

int flag=0;

char str [15] = "Zero青春工作室";

unsigned char*sp=str;

while(*sp)

{

if(*sp> 0xa0)//0xa0=160,汉字地代

{

if(! flag)

flag++;

else

{

putchar('\l');

flag--;

}

}

else

putchar('$');

sp++;


}

}

image008[3,184字节]

test04. c的目的在于搜索str字符串,当发现汉字就输出一张“笑脸”,否则就输出“$”符。

由于一个汉字占用两个字节,这两个字节的数值就称为该汉字的机内码(分别称为高字节内码和低字节内码)。test03.c中的“呸”字的机内码即为Oxc5de,这就是在中文环境下test03.c破口骂人的原因。

汉字的机内码与通常所讲的区位码是有区别的,这点在以后的内容中将会谈到。

3.支持各种汉字输入法

许多读者对这个问题很敏感,也很希望自己编制出来的程序能支持各种汉字输入法,但看了以下的内容,可能会有所失望。

因为各种输入法都是一个TSR(内存驻留)程序,它们驻留在内存里面,都是些很好的工具(当然还有些不足,这点下一小节再谈)。一旦你的“热键”激活了它,它们就会为你工作。所以从某种意义上讲,那些吹嘘“本软件支持各种流行的输入法”只是一种骗局,事实上是各种汉字输入法支持了这些软件。

既然TSR程序为我们做好了一切,我们就可以编写“支持各种汉字输入法”的程序了。

/*test05.c/

#include

main()

{

char str[80];

gotoxy(1, 20);

printf("请输入:\n");

scanf("%s", str);

}

image009[7,257字节]

运行UCDOS,这时屏幕最下面一行是“输入法提示行”。运行test05. exe,开始输入字符,在输入过程中,如果切换输入法至中文输入状态,即可输入汉字。

4.图形状态下汉字处理

图形状态下的汉字处理如同文本状态下一样简单可行:

/*test06.c/

#include

#include

main()

{

int gd=VGA, gm=VGAHI;

char str[80];

initgraph(&gd, &gm, "");

circle(200, 200, 50);

line(0, 470, 640, 470);

gotoxy(1, 20);

printf("请输入:\n");

scanf("%s", str);

closegraph();

}

image011[3,435字节]

编译运行test06. exe,进入图形状态后,出现中文提示和一条直线,可能找不到“输入法提示行”。敲击右Shift键呼出它,如同test05. c,可以用不同的输入法输入内容。

一切看起来很正常,但事实上输入法内存驻留程序还是有不足的,这可能是TSR程序的体积限制带来的问题。如果读者在输入的同时,敲击右Shift键就会隐去“输入法提示行”但是并没有因此而使原先画的一条直线再现出来,也就是说“输入法提示行”吃掉了它。不过,对于简单的程序实现,这并不太重要。否则,就必须特别地为之编写相应的中断处理程序(见第二篇)来弥补这个缺点。

5.系统环境的自动识别

我们很有可能编写过如下这样的程序:

/*test07. c*/

main()

{

printf(" \n祝可爱的李辉妹妹生日快乐!");

}

test07.c在中文环境下运行时,一切正常,而且带着温馨的祝福。然而,如果一不小心在西文DOS下运行了这个程序,我们完全可以想象,结果是多么地令人不愉快。

为了避免类似的难堪,我们必须编写出适应性很强的代码,它必须能自动地识别当前的系统环境,然后做出明智的做法,就象UCDOS的SETUP一样。

UCDOS一工作,它就会在某一个隐蔽的位置作了一个标记,因为它本身带有的那些应用程序也必须用到它。这个隐蔽的标记可以利用0x2f号中断访问到。

改进的“问候程序”如下:

/*test08.c/

#include

main()

{

char loaded;

_AX= 0xdb00;

geninterrupt(0x2f);

loaded=(_AL==0xff&&_BX==0x5450&&_DX==5);

if(loaded)

printf("\n祝可爱的李辉妹妹生日快乐!");

else

printf("\nHappy birthday to dear LiHui!");

}

在中文环境下输出:

 image013[5,947字节]

在西文环境下输出:

image016[2,457字节]

显然,不管在中文还是在西文环境下,它都不再会令你失望了(当然,糟糕的英语除外)。

本文曾经发表于《电脑爱好者》期刊杂志98年2期,版权CFan所有。

阅读(758) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~