现在的位置: 首页 > 综合 > 正文

C/C++对汉字的读取

2017年01月19日 ⁄ 综合 ⁄ 共 7957字 ⁄ 字号 评论关闭

//怎么读取汉字。
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
if((fp=fopen("D:\\123.txt","r"))==NULL)
{
printf("Error!\n");
exit(0);
}
//假设d盘的123.txt中有四个汉字:好好学习,下面的部分输出第一个汉字
char ch[3];
int i;
for(i=0;i<2;i++)
ch[i]=getc(fp);
ch[i]='\0';
puts(ch);
//假设d盘的123.txt中有四个汉字:好好学习,下面的部分输出全部汉字但是这样操作有缺陷:那就是如果有三个汉字一个字母的话,输出将发生错误。你可以将123.txt中的内容改为:学习过C ,你试一试就知道了
rewind(fp);
char ch2[9];
for(i=0;i<8;i++)
ch2[i]=getc(fp);
ch2[i]='\0';
puts(ch2);
fclose(fp);
return 0;
}
另外如果我们要想一个一个的读取汉字;我们可以这样修改代码如下。申请的空间大小有具体情况而定。
rewind(fp);
char ch[272052];
for(i=0;i<272051;i++)
{
if(i%3==2)
ch[i]='\0';
else
ch[i]=getc(fpg);
}
ch[i]='\0';
char *q=ch;
//cout<<ch<<endl;
char p[2];
for(i=0;i<181368;i++)
{
strcpy(p,q);
q+=3;
cout<<p<<endl;
}
把汉字存入数组
http://zhidao.baidu.com/question/7967174.html

http://z.baidu.com/question/147472517.html?fr=uc_push

http://z.baidu.com/question/147877384.html?fr=uc_push

今天看到一个c++学习群里的一个哥们写了一段程序:

#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
char c[10]="今天";
cout<<c<<endl;
for(int i=0;i<10;++i)
cout<<int(c[i])<<endl;
char ch[3]={-67,-15,0};
cout<<ch<<endl;
return 0;
}

启示是char可以存放汉字,但需要一个char型的长度为3的一维数组来存放汉字。接着我试着编了一个程序,如下:

#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
int i,j,k=0;
char c[20]="今天是个好天气!";
cout<<c<<endl;
for(i=0;i<16;++i)
cout<<int(c[i])<<endl;
char ch[8][3];
for(i=0;i<8;i++)
for(j=0;j<2;j++)
{
ch[i][j]=int(c[k]);
k++;
}
for(i=0;i<8;i++)
ch[i][2]=0;//这里也可以写成“ch[ i ][ 2 ]='\0';”
for(i=0;i<8;i++)
puts(ch[i]);

for(i=0;i<8;i++)
for(j=0;j<3;j++)
putchar(ch[i][j]);
return 0;
}

很有趣!

后来我问了一些网上的高手,得到了另外两串代码:

代码1:

#include <iostream>
using namespace std;
int main()
{

char c[20]="今天是个好天气!";
cout<<c<<endl;
for(int i=0;i<16;i=i+2)
cout<<c[ i ]<<c[ i+1];
return 0;
}

代码2:

#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
int i,j,k=0;
char c[20]="今天是个好天气!";
cout<<c<<endl;
for(i=0;i<16;++i)
cout<<int ( c [ i ])<<endl;
char ch[ 8 ][ 2 ];
for(i=0;i<8;i++)
for(j=0;j<2;j++)
{
ch[ i ][ j ]=int (c[ k ]);
k++;
}
// for(i=0;i<8;i++)
// ch[8][2]=0;
// for(i=0;i<8;i++)
// puts(ch[ i ]);
cout<<ch[ 0 ]<<endl;
return 0;
}

更加简练的:

#include<iostream.h>
void main()
{
int i;
char ch[100]="今天真是个好天气!";
for(i=0;i<100&&ch[i]!='\0';i++)
cout<<ch[i];
}

给我启示的另一个题目:(http://zhidao.baidu.com/question/130406681.html?push=core
#include<iostream>
using namespace std;
void Card()
{
const int x=9;
const int y=3;//the number of card
char c[y][x][5]={"一万","二万","三万","四万","五万","六万","七万","八万","九万",
"一条","二条","三条","四条","五条","六条","七条","八条","九条",
"一柄","二柄","三柄","四柄","五柄","六柄","七柄","八柄","九柄"};
for(int i = 0; i < y; i ++)
{
for(int j = 0; j < x; j++)
{
cout<<c[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
Card();
return 0;
}

原文:

http://www.vckbase.com/document/viewdoc/?id=1733

VC++的Unicode编程

作者:韩耀旭

下载源代码

以下内容来自:http://www.west263.com/info/html/chengxusheji/C-C--/20080224/10726.html

学习过C语言的人也许有时会碰到这样一个问题:如何用变量存储汉字连同对
这些变量进行操作。现在许多C语言参考书中都没涉及到这个问题,程式中多为处
理英文变量和英文字符串,涉及到汉字的情况也大都是在printf语句中输出提示
信息或结果,如:
...

printf("请输入a,b的值:\n");
printf("输出功率为%s千瓦。\n",power); 根据专家观察,这样的理论和现象都是值得各位站长深思的

,所以希望大家多做研究学习,争取总结出更多更好的经验!

  考虑到更有相当一部分人在学习和应用C语言,因此在这里向读者介绍一下笔
者在这方面摸索出来的经验。 版权申明:本站文章均来自网络.

  存储汉字应该用字符数组,这一点是肯定的,关键问题是汉字在您的电脑
系统上占几个字节。多数人会认为一个汉字肯定占两个字节,其实不然。汉字到
底占几个字节,这是随系统不同而不同的,而且还依赖于软件环境,如Visual
Basic中汉字占一个字节。能够在您的电脑上用strlen()函数测试一下,如: 对真正的成功者来说,

不论他的生存条件如何,都不会自我磨灭

printf("%d",strlen("电脑")); ..

  若输出为6,则每个汉字占两个字节;若输出12,则每个汉字占四个字节。大
多数系统是每个汉字占两个字节的,即上述语句输出值为6。应当注意的是个全
角字符(包括标点符号)同汉字占据相同的字节。本文假定每个汉字占两个字节。 版权申明:本站文

章均来自网络,如有侵权,请联系028-86262244-215,我们收到后立即删除,谢谢!

  这样您就能够用字符数组存储汉字了,但别忘了,由于C语言中字符串是以
'\0'作为结束标记的,系统会自动加上这个标记符,而用strlen()函数测试的返
回值不包括这个'\0',因此在定义和初始化字符数组时应当使数组长度最小为实际
字符串长再加1,如: .

static char name[7]="孙悟空"; /*数组长度为7说明最多可存放3个汉字*/ .

  假如把数组长度定义为6,系统在编译时并不报错,但是当运行程式时有时会
莫名其妙地重复输出或多输出汉字,假如出现这种情况,应当首先考虑数组长度
是否有问题。当然在定义的同时初始化能够省略数组长度,如: .

static char array[]={"中国电脑软件专业技术水平考试"}; .

  同样能够定义二维数组,下面这个二维数组能够存放10个人名: 版权申明:本站文章均来自网络.

char member[10][8]; /*10个元素,每个元素中最多能放3个汉字(不是4个!)*/ 版权申明:本站文章

均来自网络,如有侵权,请联系028-86262244-215,我们收到后立即删除,谢谢!

  因为二维数组member[10][8]能够看成特别的一维数组member[0],member[1],
…,member[9],这些一维数组分别表示各行,而一行就表示了一个人名,因此如
果想操作每个人名,只需写成member[0],member[1],…而不写成member[0][8],
member[1][8],…。 特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画

,设计作品,如需使用,请与原作者联系

  顺便提一下,在C编译窗口中输入汉字需要中文环境。假如读者用的是DOS操
作系统,那么就需要安装CCDOS或UCDOS;假如是WIN95/98操作系统,则在DOS命令
窗口中运行下面这个批处理文档即可,而不必另外安装中文DOS系统: 本站所提供的摄影照片,插画,

设计作品,如需使用,请与原作者联系。

C:\WINDOWS>PDOS95 ..

  在C编辑窗口中用Ctrl 空格键启动WIN95中文输入法。另外由于C程式是基于
DOS的,因此编辑、编译C程式最好在全屏幕状态,否则容易出现问题。 ..

  下面给出一个实例程式,他的功能是计算出输入年份的天干地支。 ..

#include "string.h"
main()
{
int a,b,year;
char gz[6]; /*用来表示干支的字符变量*/
/*注意:下面两个语句中{}内的引号和逗号不能为全角字符*/
static char tg[10][3]={"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
static char dz[12][3]={"子","丑","寅","卯","辰","巳","午","未","申","酉","戍","亥"};
printf("请输入一个年份:");
scanf("%d",&year);
a=(year-1804) ; /*以1804年为参考年份,1804年是甲子年*/
b=(year-1804) ;
strcpy(gz,tg[a]);
strcat(gz,dz);
printf("%d年的干支为:%s\n",year,gz);
} ...

  运行结果:
请输入一个年份:1999

以下内容来自:http://topic.csdn.net/t/20031030/13/2410064.html

前面陆陆续续写了一些在TC中显示汉字的帖子,但都没有太详细的讲解,现在从前到后系统讲一下。

一、汉字在计算机中的编码形式
我们都知道,在计算机中英文字符是用一个字节的ASCII码表示,该字节最高位一般用做奇偶校验,故实际是用7位码来代表128个字符的,但是对于众多的汉字,只有用两个字节才能表示,这样用两个字节来表示一个汉字的体制,国家制定了统一的标准,称为国标码。国标码规定,组成两个汉字代码的各字节最高位为0,这和英文字符表示方法相同,这就有可能把汉字的国标码看作两个ASCII码,为此又规定在计算机里表示汉字时,把最高位置1,表示该码是汉字,这种最高位为1的代码称为机器内的汉字代码,简称内码。计算机里汉字就是用内码表示的。
例如:“大”这个汉字,
国标码 3473 00110100 01110011
内码 B4F3 10110100 11110011
知道汉字在计算机里是用内码表示的以后,还需要知道具体汉字的结构。我国在1981年公布了《通讯用汉字字符集及其交换码标准》GB2312-80方案,里面规定了高频字、常用字、次常用字集合成汉字基本字符集(共6763个),再加上一些西文字母,希腊字母、日文字符、图形符号等一共700个。国家标准的汉字字符集在汉字操作系统中是以汉字库的形式提供的。汉字库规定,把字库分为94个区(区号),每个区有94个汉字(位号),这就是所谓的区位码(区位码第一字节是区号,第二字节是位号,因为知道了区位码就等于知道了该汉字在字库中的位置)。每个汉字在字库中是以点阵字模形式存储的,如一般采用16*16点阵形式,这样就需要32字节。在16*16点阵里,存1的点在显示时为一个亮点,存0的点不显示,这样汉字就显示出来了。简单写一下“大”这个字的字模:
0000001100000000
0000001100000000
0000001100000000
0000001100000010
1111111111111110
0000001100000000
0000001100000000
0000001100000000
0000001100000000
0000001110000000
0000011001000000
0000110000100000
0001100000010000
0001000000011000
0010000000001110
1100000000000100
这样当需要显示“大”这个汉字时,首先把这个字模取出,然后逐位显示,1显示0不显示,屏幕上就会出现“大”这个汉字。
那么我们怎么知道汉字的区位码呢?前面说了,汉字在计算机里是用内码存储的。内码和区位码的转换关系是(还以“大”为例):
区号:B4-A0 位号:F3-A0
也就是说,把内码减去A0就是区位码,那么“大”这个汉字的区位码就出来了,是在14H区53H号,也就是第20区第83号。那么由于每个区有94个汉字,“大”这个字应该就是在汉字库的第(20-1)*94+(83-1)个汉字位置(每个汉字字模占32字节)。那么现在又要问了,内码又是怎样得到的呢?看下面的程序:
main()
{
unsigned char *s="大";
printf("%x,%x\n",s[0],s[1]);
getch();
}
运行程序发现,输出就是b4,f3。

二、西文方式下显示中文
说到这儿,大家应该有个思路了吧。要想显示汉字:
(1) 获得汉字内码
(2) 换算成区位码
(3) 在字库中取出该汉字的字模(共32字节)
(4) 1显示0不显示
说到这儿,又有一点要说明,由于汉字是16*16点阵结构,说明在一般的西文方式下还不行,因为一般的西文方式,屏幕显示都是80*25的文本格式,要想显示中文,必须切换到图形模式,在图形模式下才有象素的概念。
下面是一个实际的例子,大家可以复制到TC里运行一下就知道了。

#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "graphics.h"

void WriteHzStr();
void WriteHz(unsigned char,unsigned char,int,int);
void GetHzBit(unsigned char,unsigned char);

char *s="中华人民共和国";
FILE *fp;
long int fpos; /*具体汉字在字库中的偏移量*/
char bitdata[32]; /*存储汉字字模*/

main()
{
int gdrive=DETECT,gmode;
initgraph(&gdrive,&gmode,""); /*加载图形模式*/
if((fp=fopen("c:\\hzk16","rb"))==NULL) /*打开16*16点阵汉字字库*/
{
printf("cannot open file\n");
exit(0);
}
WriteHzStr();
fclose(fp);
closegraph();
getch();
}

void WriteHzStr()
{
int num,i,x,y;
num=strlen(s); /*获取字符串长度*/
x=0,y=0;
for(i=0;i<num;i+=2) /*每次读两个字节*/
{
WriteHz(s[i],s[i+1],x,y);
x+=16;
if(x>=640) {y+=16;x=0;}
}
}

void WriteHz(unsigned char left,unsigned char right,int x,int y)
{
unsigned char bit[8]={128,64,32,16,8,4,2,1};
int i,j;
GetHzBit(left,right);
for(i=0;i<16;i++)
for(j=0;j<8;j++) /*和bit[]与操作以后,在屏幕上画点*/
{
if(bitdata[2*i]&bit[j]) putpixel(x+j,i+y,YELLOW);
if(bitdata[2*i+1]&bit[j]) putpixel(x+8+j,i+y,YELLOW);
}
}

void GetHzBit(unsigned char left,unsigned char right)
{
fpos=32L*((left-161)*94+(right-161)); /*获得字模在字库中的位置*/
fseek(fp,fpos,SEEK_SET);
fread(bitdata,32,1,fp); /*把该汉字字模读入到bitdata中*/
}

说明一点,上面用到的汉字库文件hzk16在UCDOS里可以找到,大小是262K。

三、中文模式下显示中文
这个问题比较简单,就是先进入UCDOS等类似的中文平台,然后一切和普通的字符串显示类似。看下面的程序:

main()
{
char *s="中华人民共和国";
printf("%s\n",s);
getch();
}

运行此程序前先进入UCDOS等中文平台,所以由于各计算机不一定都装有UCDOS,使得程序移植性不强,所以一般都不这样使用,而采用前面说的西文模式下显示中文。

注明:这里只是16*16的汉字,如果想使用24*24的,或者正楷,黑体、隶书等汉字字体,就需要使用不同的汉字库,例如hzk24k(正楷),hzk24h(黑体)等等。

 
转自:http://www.cnblogs.com/this-543273659/archive/2011/07/26/2117200.html
 
测试汉字:
下面程序来自百度知道,仅供参考,肯定还有问题。
#include<stdio.h>
int main(void)
{
char s[20];
int i,j;
char a,c[3];
FILE * fp;
scanf("%s",s);
fp=fopen(s,"r");
if(!fp){
printf("open error\n");
return 1;
}
i=0;
c[2]='\0';
while((a=fgetc(fp))!=EOF){
if(a&0x80){
c[i]=a;
i++;
if(i==2){
printf("%s 是汉字\n",c);
i=0;
}
}
else i=0;
}
getchar();
getchar();
return 0;
}
 

 

抱歉!评论已关闭.