/*在C程序中显示汉字*/
/* 在许多C程序设计中,要用到汉字进行提示或人机交互,而现行的Turbo C集成开发环境不是汉化的,如何编制能显示汉字的C程序呢? */
/* 下面的方法可以帮你在西文环境下显示汉字。这种方法是调用中文汉字库进行汉字显示。国家标准规定:汉字库分94个区,每个区有94个汉字(以位作区别),每个汉字在汉字库中有确定的区和位编号,这就是汉字的区位码。每个汉字在库中是以点阵字模形式存储的,一般采用16×16点阵(32字节)、24×24点阵(72字节),每个点用一个二进制位(0或1)表示,对应在屏幕上显示出来,就是相应的汉字。 */
/* 由于在中文环境下,输入的是汉字的内码,我们必须将之转换成区位码,算出偏移量,从字库中找到对应的汉字,将其字模显示即可。 */
/* 内码转换成区位码方法如下: */
/* qh=c1-0xa0 wh=c2-0xa0 */
/*  其区位码就是: */
/* qw=qh*0xff+wh */
/*  该汉字在字库中离起点的位置是: */
/* offset=(94*(qh-1)+(wh-1))*32L */
/* 程序例: */
/*在tc2通过*/
#include <graphics.h>
#include <stdio.h> 
#include <fcntl.h> 
#include <io.h> 
#include <stdlib.h> 
#include <conio.h>#define ROW 1 /*纵坐标放大倍数 */#define COL 2 /*横坐标放大倍数 */void main()  { int x,y;
char *s="汉字显示程序";
FILE *fp; 
char buffer[32]; /*buffer用来存储一个汉字 */
register m,n,i,j,k;
unsigned char qh,wh;
unsigned long offset;
int gd=DETECT,gm; /*图形屏幕初始化*/
initgraph(&gd,&gm," ");
if ((fp=fopen("c:hzk16","rb"))==NULL)
/*//打开汉字库,该字库可以在ucdos中找到*/
{
printf("Can't open haz16,Please add it"); 
getch();
closegraph();
exit(0); 

x=20; y=100; /*显示位置设置 */
while(*s) 
{
qh=*(s)-0xa0; /*汉字区位码*/
wh=*(s+1)-0xa0; 
offset=(94*(qh-1)+(wh-1))*32L; /*计算该汉字在字库中偏移量 */
fseek(fp,offset,SEEK_SET); 
fread(buffer,32,1,fp); /*取出汉字32字节的点阵字模存入buffer中(一个汉字) */
for (i=0;i<31 ;i++ )
{
printf ( "i = " & %d & " , buffer = "& %d,i,buffer(i)
}
for(i=0;i<16;i++) /*将32位字节的点阵按位在屏幕上打印出来(1:打印,0:不打印),显示汉字 */
for(n=0;n<ROW;n++) 
for(j=0;j<2;j++) 
for(k=0;k<8;k++) 
for(m=0;m<COL;m++) 
if (((buffer[i*2+j]>>(7-k))&0x1)!=NULL) 
putpixel(x+8*j*COL+k*COL+m,y+i*ROW+n,GREEN); 
s+=2; /*//因为一个汉字内码占用两个字节,所以s必须加2 */
x+=30; 

getch(); 
closegraph(); 
}       ●  ●  ●   ●     ●       ●    
   ●●●●● ●●●●●●     ●     ●     
  ● ●   ● ●          ●   ●  ●   
 ●   ● ●   ●      ●●●●●●●●●●●●  
●  ●        ●     ●    ●    ●   
  ● ● ●●●●●●●●    ●    ●    ●   
  ●         ●     ●●●●●●●●●●●   
  ●  ●●●●●  ●     ●    ●    ●   
  ●  ●   ●  ●     ●    ●    ●   
  ●  ●   ●  ●     ●●●●●●●●●●●   
  ●  ●●●●●  ●     ●    ●        
  ●  ●   ●  ●          ●     ●  
  ●  ●   ●  ●   ●●●●●●●●●●●●●●● 
  ●  ●●●●●  ●          ●        
  ●       ● ●          ●        
  ●        ●           ●        

解决方案 »

  1.   

    以前写过(QB的):'汉字
    '-- 字库控制 (Char Lib) ------------------------------------------------------
    DECLARE FUNCTION OpenHZ16% (Path$)
    DECLARE SUB CloseHZ16 ()DIM SHARED Open16True AS INTEGER, En8x16File AS INTEGER, Ch16x16File AS INTEGER'-- 显示 (Echo) --------------------------------------------------------------
    DECLARE SUB SetVGAMem ()
    DECLARE SUB MemLineBF13 (BYVAL X1%, BYVAL Y1%, BYVAL X2%, BYVAL Y2%, BYVAL C AS INTEGER)DIM SHARED ViewMaxX AS INTEGER, ViewMaxY AS INTEGERCONST ScreenWidth = 320
    CONST ScreenHeight = 200CONST DrawNormal = 0
    CONST DrawNot = &H100
    CONST DrawAnd = &H200
    CONST DrawOr = &H300
    CONST DrawXor = &H400
    CONST DrawEqv = &H500
    CONST DrawImp = &H600'-- 单个字符 (A Char) --------------------------------------------------------
    DECLARE SUB WriteAEn (AscCode AS INTEGER, X%, Y%, H!, V!, C AS INTEGER)
    DECLARE SUB WriteACh (Qu AS INTEGER, Wei AS INTEGER, X%, Y%, H!, V!, C AS INTEGER)DIM SHARED BitInt(1 TO 16) AS INTEGER'-- 多个字符 (Many Char) -----------------------------------------------------
    DECLARE SUB HZPrint (ChStr AS STRING, X%, Y%, H!, V!, Hd%, Vd%, C%, BgC%)
    DECLARE SUB SetTextSize (H AS SINGLE, V AS SINGLE, Hd AS INTEGER, Vd AS INTEGER)
    DECLARE SUB SetTextStyle (C AS INTEGER, BgC AS INTEGER, Lf AS INTEGER)
    DECLARE FUNCTION FindCrLf! (FindStr AS STRING, CrLfLen AS INTEGER)
    DECLARE SUB CPrint (X%, Y%, ChStr AS STRING)TYPE RectB
        X1 AS INTEGER
        Y1 AS INTEGER
        X2 AS INTEGER
        Y2 AS INTEGER
    END TYPETYPE LblStyle
        Rect AS RectB
        C AS INTEGER
        BgC AS INTEGER
        H AS SINGLE
        V AS SINGLE
        Hd AS INTEGER
        Vd AS INTEGER
        Lf AS INTEGER
    END TYPEDECLARE SUB CPrintEx (ChStr AS STRING, StrStyle AS LblStyle)DIM SHARED TextC AS INTEGER, TextBgC AS INTEGER, TextLf AS INTEGER
    DIM SHARED TextH AS SINGLE, TextV AS SINGLE, TextHd AS INTEGER, TextVd AS INTEGERDIM SHARED qbCrLf AS STRING'== 赋值 (Let) ===============================================================
    DIM I AS INTEGERFOR I = 1 TO 8
        BitInt(I) = 2 ^ (8 - I)NEXT I
    BitInt(9) = &H8000: BitInt(10) = &H4000
    FOR I = 11 TO 16
        BitInt(I) = BitInt(I - 1) / 2NEXT IViewMaxX = 319: ViewMaxY = 199
    TextC = 15: TextBgC = 0: TextLf = -1
    TextH = 1: TextV = 1: TextHd = 0: TextVd = 0qbCrLf = CHR$(13) + CHR$(10)'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    DIM Lbl1 AS LblStyleSCREEN 13I = OpenHZ16("")
    'IF I <> 0 THEN PRINT "Cann't Find FONT!": ENDSetVGAMem
    WriteACh 16, 1, 0, 0, 1, 1, 12
    WriteAEn 33, 16, 0, 1, 1, 4HZPrint "啊!", 0, 16, 1, 1, 0, 0, 12, 1SetTextStyle 0, 7, -1
    SetTextSize 2, 2, 1, 0
    CPrint 0, 32, "啊!"Lbl1.Rect.X1 = 0
    Lbl1.Rect.Y1 = 64
    Lbl1.Rect.X2 = 60
    Lbl1.Rect.Y2 = 160
    Lbl1.C = 8
    Lbl1.BgC = 14
    Lbl1.H = 3
    Lbl1.V = 3
    Lbl1.Hd = 0
    Lbl1.Vd = 0
    Lbl1.Lf = 0
    CPrintEx "啊!" + qbCrLf + "1", Lbl1CloseHZ16ENDSUB CloseHZ16
        IF Open16True THEN
            CLOSE En8x16File
            CLOSE Ch16x16File    END IFEND SUBSUB CPrint (X%, Y%, ChStr AS STRING)
        DIM TempStr1 AS STRING, TempStr2 AS STRING
        DIM Find AS INTEGER, LenCrLf AS INTEGER
        DIM TempY  AS INTEGER, TempWidth AS INTEGER    SetVGAMem
        'HZPrint ChStr, X%, Y%, TextH, TextV, TextHd, TextVd, TextC, TextBgC    TempStr1 = ChStr
        TempY = Y%: TempWidth = ViewMaxX - X% + 1    DO
            Find = FindCrLf(TempStr1, LenCrLf)
            IF Find THEN
                TempStr2 = LEFT$(TempStr1, Find - 1)
                TempStr1 = MID$(TempStr1, Find + LenCrLf)
                HZPrint TempStr2, X%, TempY, TextH, TextV, TextHd, TextVd, TextC, TextBgC
                IF TempStr1 = "" THEN EXIT DO
                IF TextLf THEN
                    TempY = TempY + INT((CLNG(LEN(TempStr2)) * CINT(TextH * 8 + TextHd) - TextHd) \ TempWidth + 1) * CINT(TextV * 16 + TextVd) - TextVd            ELSE
                    TempY = TempY + CINT(TextV * 16)            END IF
                IF TempY > ViewMaxY THEN EXIT DO        ELSE
                HZPrint TempStr1, X%, TempY, TextH, TextV, TextHd, TextVd, TextC, TextBgC
                EXIT DO        END IF    LOOPEND SUBSUB CPrintEx (ChStr AS STRING, StrStyle AS LblStyle)
        DIM TempNum AS INTEGER    SWAP ViewMaxX, StrStyle.Rect.X2
        SWAP ViewMaxY, StrStyle.Rect.Y2
        SWAP TextC, StrStyle.C
        SWAP TextBgC, StrStyle.BgC
        SWAP TextLf, StrStyle.Lf
        SWAP TextH, StrStyle.H
        SWAP TextV, StrStyle.V
        SWAP TextHd, StrStyle.Hd
        SWAP TextVd, StrStyle.Vd    TempNum = TextBgC
        TextBgC = -1
        IF TempNum <> -1 THEN
            SetVGAMem
            MemLineBF13 StrStyle.Rect.X1, StrStyle.Rect.Y1, ViewMaxX, ViewMaxY, TempNum    END IF    CPrint StrStyle.Rect.X1, StrStyle.Rect.Y1, ChStr    TextBgC = TempNum
        SWAP ViewMaxX, StrStyle.Rect.X2
        SWAP ViewMaxY, StrStyle.Rect.Y2
        SWAP TextC, StrStyle.C
        SWAP TextBgC, StrStyle.BgC
        SWAP TextLf, StrStyle.Lf
        SWAP TextH, StrStyle.H
        SWAP TextV, StrStyle.V
        SWAP TextHd, StrStyle.Hd
        SWAP TextVd, StrStyle.VdEND SUBFUNCTION FindCrLf (FindStr AS STRING, CrLfLen AS INTEGER)
        DIM FindCr AS INTEGER, FindLf AS INTEGER    FindCr = INSTR(FindStr, CHR$(13))
        FindLf = INSTR(FindStr, CHR$(10))
        CrLfLen = 1    IF FindCr = 0 THEN
            IF FindLf = 0 THEN
                FindCrLf = 0        ELSE
                FindCrLf = FindLf        END IF    ELSE
            IF FindLf = 0 THEN
                FindCrLf = FindCr        ELSE
                IF FindCr < FindLf THEN
                    FindCrLf = FindCr
                    IF FindCr + 1 = FindLf THEN CrLfLen = 2            ELSE
                    FindCrLf = FindLf            END IF        END IF    END IFEND FUNCTION
      

  2.   


    SUB HZPrint (ChStr AS STRING, X%, Y%, H!, V!, Hd%, Vd%, C%, BgC%)
        DIM StrLen AS INTEGER
        DIM Addr AS INTEGER
        DIM Char1 AS INTEGER, Char2 AS INTEGER
        DIM DrawX AS INTEGER, DrawY AS INTEGER
        DIM DrawBg AS INTEGER    StrLen = LEN(ChStr)
        IF StrLen = 0 THEN EXIT SUB
        Addr = 1
        DrawX = X%: DrawY = Y%
        IF DrawX > ViewMaxX THEN EXIT SUB
        IF DrawY > ViewMaxY THEN EXIT SUB
        IF H! <= 0 THEN H! = 1
        IF V! <= 0 THEN V! = 1
        IF BgC% <> -1 THEN DrawBg = -1: BgC = BgC AND &HFF    DO
            Char1 = ASC(MID$(ChStr, Addr))
            IF Char1 > 160 AND Char1 <= 247 THEN
                Char2 = ASC(MID$(ChStr, Addr + 1))
                IF Char2 > 160 AND Char2 <= 254 THEN
                    IF TextLf THEN
                        IF DrawX + CINT(H! * 16) > ViewMaxX THEN DrawX = X%: DrawY = DrawY + V! * 16 + Vd%
                        IF DrawY > ViewMaxY THEN EXIT DO                ELSE
                        IF DrawX > ViewMaxX THEN EXIT DO                END IF
                    IF DrawBg THEN MemLineBF13 DrawX, DrawY, DrawX + CINT(H! * 16) - 1, DrawY + CINT(V! * 16) - 1, BgC%
                    WriteACh Char1 - 160, Char2 - 160, DrawX, DrawY, H!, V!, C%
                    DrawX = DrawX + H! * 16 + Hd%            ELSE
                    IF TextLf THEN
                        IF DrawX + CINT(H! * 8) > ViewMaxX THEN DrawX = X%: DrawY = DrawY + V! * 16 + Vd%
                        IF DrawY > ViewMaxY THEN EXIT DO                ELSE
                        IF DrawX > ViewMaxX THEN EXIT DO                END IF
                    IF DrawBg THEN MemLineBF13 DrawX, DrawY, DrawX + CINT(H! * 8) - 1, DrawY + CINT(V! * 16) - 1, BgC%
                    WriteAEn Char1, DrawX, DrawY, H!, V!, C%
                    DrawX = DrawX + H! * 8 + Hd%                IF TextLf THEN
                        IF DrawX + CINT(H! * 8) > ViewMaxX THEN DrawX = X%: DrawY = DrawY + V! * 16 + Vd%
                        IF DrawY > ViewMaxY THEN EXIT DO                ELSE
                        IF DrawX > ViewMaxX THEN EXIT DO                END IF
                    IF DrawBg THEN MemLineBF13 DrawX, DrawY, DrawX + CINT(H! * 8) - 1, DrawY + CINT(V! * 16) - 1, BgC%
                    WriteAEn Char2, DrawX, DrawY, H!, V!, C%
                    DrawX = DrawX + H! * 8 + Hd%            END IF
                Addr = Addr + 2        ELSE
                IF TextLf THEN
                    IF DrawX + CINT(H! * 8) > ViewMaxX THEN DrawX = X%: DrawY = DrawY + V! * 16 + Vd%
                    IF DrawY > ViewMaxY THEN EXIT DO            ELSE
                    IF DrawX > ViewMaxX THEN EXIT DO            END IF
                IF DrawBg THEN MemLineBF13 DrawX, DrawY, DrawX + CINT(H! * 8) - 1, DrawY + CINT(V! * 16) - 1, BgC%
                WriteAEn Char1, DrawX, DrawY, H!, V!, C%
                DrawX = DrawX + H! * 8 + Hd%            Addr = Addr + 1        END IF
            IF Addr > StrLen THEN EXIT DO    LOOPEND SUBSUB MemLineBF13 (BYVAL X1%, BYVAL Y1%, BYVAL X2%, BYVAL Y2%, BYVAL C AS INTEGER)
         DIM I AS INTEGER, J AS INTEGER, Addr AS LONG
         DIM PsetStyle AS INTEGER
         DIM TempNum1 AS INTEGER, TempNum2 AS INTEGER     IF X1% > X2% THEN SWAP X1%, X2%
         IF Y1% > Y2% THEN SWAP Y1%, Y2%
         IF X1% < 0 THEN Y1% = 0
         IF Y1% < 0 THEN Y1% = 0
         IF X2% > ViewMaxX THEN X2% = ViewMaxX
         IF Y2% > ViewMaxY THEN Y2% = ViewMaxY
         PsetStyle = C AND &H700
         IF PsetStyle = &H700 THEN PsetStyle = 0
         C = C AND &HFF     IF PsetStyle = DrawNormal THEN
            FOR I = X1% TO X2%
                FOR J = Y1% TO Y2%
                    POKE CLNG(J) * ScreenWidth + I, C            NEXT J        NEXT I     ELSE
            FOR I = X1% TO X2%
                FOR J = Y1% TO Y2%
                    Addr = CLNG(J) * ScreenWidth + I
                    IF PsetStyle = DrawNot THEN
                        TempNum1 = C XOR &HFF                ELSE
                        TempNum2 = PEEK(Addr)
                        SELECT CASE PsetStyle
                        CASE DrawAnd
                            TempNum1 = C AND TempNum2
                        CASE DrawOr
                            TempNum1 = C OR TempNum2
                        CASE DrawXor
                            TempNum1 = C XOR TempNum2
                        CASE DrawEqv
                            TempNum1 = C EQV TempNum2
                        CASE DrawImp
                            TempNum1 = C IMP TempNum2
                        END SELECT                END IF
                    POKE Addr, TempNum1            NEXT J        NEXT I
         END IFEND SUBFUNCTION OpenHZ16% (Path$)
        DIM TempNum AS INTEGER    ON ERROR RESUME NEXT    TempNum = 1
        En8x16File = FREEFILE
        OPEN Path$ + "En8x16.fon" FOR BINARY ACCESS READ LOCK WRITE AS En8x16File
        IF ERR <> 0 THEN OpenHZ16% = 1: EXIT FUNCTION
        'PRINT LOF(En8x16File)
        IF LOF(En8x16File) < 4096 THEN OpenHZ16% = 3: EXIT FUNCTION    ON ERROR GOTO 0
        ON ERROR RESUME NEXT    TempNum = 2
        Ch16x16File = FREEFILE
        OPEN Path$ + "Ch16x16.fon" FOR BINARY ACCESS READ LOCK WRITE AS Ch16x16File
        IF ERR <> 0 THEN OpenHZ16% = 2: EXIT FUNCTION
        'PRINT LOF(Ch16x16File)
        IF LOF(Ch16x16File) < 267616 THEN OpenHZ16% = 4: EXIT FUNCTION    ON ERROR GOTO 0
        Open16True = -1END FUNCTIONSUB SetTextSize (H AS SINGLE, V AS SINGLE, Hd AS INTEGER, Vd AS INTEGER)
        TextH = H
        TextV = V
        TextHd = Hd
        TextVd = VdEND SUBSUB SetTextStyle (C AS INTEGER, BgC AS INTEGER, Lf AS INTEGER)
        TextC = C
        TextBgC = BgC
        TextLf = LfEND SUBSUB SetVGAMem
        DEF SEG = &HA000END SUBSUB WriteACh (Qu AS INTEGER, Wei AS INTEGER, X%, Y%, H!, V!, C AS INTEGER)
        DIM FileAddr AS LONG
        DIM TempInt AS INTEGER
        DIM I AS INTEGER, J AS INTEGER    FileAddr = CLNG((Qu - 1) * 94 + (Wei - 1)) * 32
        IF FileAddr < 0 OR FileAddr > 267616 THEN EXIT SUB    FOR I = 0 TO 15
            GET Ch16x16File, FileAddr + I * 2 + 1, TempInt
            FOR J = 1 TO 16
                IF TempInt AND BitInt(J) THEN MemLineBF13 X% + CINT((J - 1) * H!), Y% + CINT(I * V!), X% + CINT(J * H!) - 1, Y% + CINT((I + 1) * V!) - 1, C        NEXT J    NEXT IEND SUBSUB WriteAEn (AscCode AS INTEGER, X%, Y%, H!, V!, C AS INTEGER)
        DIM FileAddr AS LONG
        DIM TempInt AS INTEGER
        DIM I AS INTEGER, J AS INTEGER    FileAddr = AscCode * 16
        IF FileAddr < 0 OR FileAddr > 267616 THEN EXIT SUB    FOR I = 0 TO 15
            GET En8x16File, FileAddr + I + 1, TempInt
            FOR J = 1 TO 8
                IF TempInt AND BitInt(J) THEN MemLineBF13 X% + CINT((J - 1) * H!), Y% + CINT(I * V!), X% + CINT(J * H!) - 1, Y% + CINT((I + 1) * V!) - 1, C        NEXT J    NEXT IEND SUB
      

  3.   

    16点阵字库名为“En8x16.fon”!由于采用了字节写屏画点(MemLineBF13),所以速度比较快!