每个汉字的图形都由 16×16 的点阵组成,如汉字“福”的点阵图形如下:
每个像素用 1 个二进制位来表示:1 表示像素是亮的,0 表示像素是不亮的。每个汉字由 16×16 = 256 个二进制位,即 32 个字节组成。
HZK16.DAT 是汉字点阵图形文件,其中包括 GB2312-80 的全部汉字图形,按汉字的区位码顺序存储。
请编写函数,显示汉字的图形。
函数原型
// 显示点阵汉字图形
void ShowImage(unsigned char high, unsigned char low, FILE *f, int bold, int italic);
说明:参数 high
和 low
分别为汉字内码的高字节和低字节,f
是指示汉字图形库文件的指针。参数 bold
为逻辑值,若为 1(真),则为粗体,否则不加粗。参数 italic
为逻辑值,若为 1(真),则为斜体,否则不倾斜。
该函数用“■”表示汉字点阵中点亮的像素,用“□”表示不亮的像素。
裁判程序
下面的程序输入汉字,输出该汉字的点阵图形。
#include <stdio.h>
// 显示点阵汉字图形
void ShowImage(unsigned char high, unsigned char low, FILE *f, int bold, int italic);
int main()
{
char high, low, bold, italic;
scanf(" %c%c %c %c", &high, &low, &bold, &italic);
FILE *f = fopen("HZK16.DAT", "rb");
if (f)
{
ShowImage(high, low, f, bold == 'Y', italic == 'Y');
fclose(f);
}
return 0;
}
......
/* 你提交的代码将被嵌在这里 */
输入格式
汉字 粗体(Y/N) 斜体(Y/N)
输出格式
指定格式的汉字
输入样例1
福 N N
输出样例1
输入样例2
福 N Y
输出样例2
输入样例3
福 Y N
输出样例3
输入样例4
福 Y Y
输出样例4
void ShowImage(unsigned char high, unsigned char low, FILE *f, int bold, int italic)
{
int i,j,k;
unsigned char buffer[32]; //存储一个汉字所用的32个字节
long int offset;
offset = ((high - 0xa1) * 94 + low - 0xa1) * 32; //计算绝对偏移地址
fseek(f,offset,0); //根据偏移寻找到该字字模的第一个字节
for (i = 0; i < 32; ++i) { //连续读取32个字节
buffer[i] = fgetc(f);
}
if(bold==0&&italic==0)
for (i = 0; i < 32; ++i) { //将32个字节顺序打印
for (j = 0; j < 8; ++j) {
if (buffer[i] & 0x80) {
printf("■");
}else{
printf("□");
}
buffer[i] <<= 1;
}
if (i % 2) {
printf("\n"); //如果i%2==1说明该字节是靠后的那个字节,显示完后要换行
}
}
else if(bold==0&&italic==1)
for (i = 0; i < 32; ++i) { //将32个字节顺序打印
if (i%2==0) { //斜体空格输出
for(k=0;k<(30-i)/2;k++)
printf(" ");
}
for (j = 0; j < 8; ++j) {
if (buffer[i] & 0x80) {
printf("■");
}else{
printf("□");
}
buffer[i] <<= 1;
}
if (i % 2) {
printf("\n"); //如果i%2==1说明该字节是靠后的那个字节,显示完后要换行
}
}
else if(bold==1&&italic==0)
for (i = 0; i < 32; ++i) { //将32个字节顺序打印
for (j = 0; j < 8; ++j) {
if (buffer[i] & 0x80) {
printf("■■");
}else{
printf("□□");
}
buffer[i] <<= 1;
}
if (i % 2) {
printf("\n"); //如果i%2==1说明该字节是靠后的那个字节,显示完后要换行
}
}
else if(bold==1&&italic==1)
for (i = 0; i < 32; ++i) { //将32个字节顺序打印
if (i%2==0) { //斜体空格输出
for(k=0;k<(30-i)/2;k++)
printf(" ");
}
for (j = 0; j < 8; ++j) {
if (buffer[i] & 0x80) {
printf("■■");
}else{
printf("□□");
}
buffer[i] <<= 1;
}
if (i % 2==1) {
printf("\n"); //如果i%2==1说明该字节是靠后的那个字节,显示完后要换行
}
}
}