您的位置:首页 > 其它

对于宽字符的初步运用

2015-10-26 22:50 351 查看
最近要用到宽字符,于是乎学习了两天关于宽字符方面的东西

宽字符是双字节多语言字符代码,最简单来说中文一般就可以用宽字符来表示,因为一个中文占用两个字节,如果直接输出会导致乱码。

我用的是codeblocks,可能会需要更改一下编码形式(如果依照本文代码发现会报错的话极有可能是编码问题)

方法是:打开codeblocks-settings-compiler,在窗口下选择other options在下面的窗口输入

-finput-charset=GBK

-fexec-charset=GBK

即可。

首先包含头文件#i nclude <wchar.h>

定义一个宽字符:wchar_t  变量名='定义的值';

例 wchar_t c='A';

定义一个指向宽字符的指针wchar_t  *指针名=L"内容";

例 wchar_t *p=L“hello";

定义一个宽字符字符数组 wchar_t   数组名[]=L"内容";

例 wchar_t  p[]=L"hello";

相对应于字符串的strlen,strcmp,strcpy,同样对于宽字符有自己的一套函数,详细比对可参照http://blog.chinaunix.net/uid-20454812-id-1675838.html

举几个常见的:

  如果定义了 wchar_t *p=L"hello";

  wcslen(p)的返回值就是5

mbstowcs()非常好用,比如我输入的一段话是用普通字符串保存的,可以将其转成宽字符串处理,使用方法mbstowcs(宽字符串,原来的普通字符串,截取的长度)

wcstombs/mbstowcs是实现转换的一对函数. 这两个c的库函数其实内部也就是对刚刚windows的api和接下来我们要说的iconv的封装。使用时要注意,如果涉及到中文,要先setlocale,当设置好正确的locale,函数内部才能找到正确的字符集进行转换。

设置方法:setlocale( LC_ALL, "CHS" ); //将CHS设为你系统用的编码

我的相关代码:目的,识别出标题,并且标题的两边加标签<section>和</section>而如果是内容则加标签<maintext>和<maintext>(当然两边也要加section),文章开头结尾分别加<docunment>和</docunment>

#include <stdio.h>
#include <Windows.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <locale.h>
#ifndef UNICODE
#define UNICODE
#endif

#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif
#endif
FILE *fp2;
int formnum;//记录之前出现了几种格式
int Find(char p[],char ch)
{
int l=strlen(p);
int i;
for (i=0;i<10;i++)
if (p[i]==ch)
return 1;
return 0;
}
int find(int p[],int k)
{
int i;
for (i=0;i<formnum;i++)
if (p[i]==k)
return 1;
return 0;
}
int findchinese(wchar_t p[],wchar_t t[])
{
int i,l;
wchar_t *q;
l=wcslen((wchar_t*)p);
for (i=0;i<l;i=i+1)
if((q=wcschr((wchar_t*)t,p[i]))!=NULL)
return 1;
return 0;
}
int main()
{
setlocale( LC_ALL, "CHS" ); //将CHS设为你系统用的编码
FILE *fp;
char s[1000][1000];//最重要的二维数组,存储已经访问过的所有节点
int i,k;
int sum;//sum的作用是判断是哪种格式和是否含有关键区分的数字和符号
int form[1000];//存储之前出现的格式
int num;//代表是存储的maintext的第几行
char temp[1000][1000];//用来存储普通段落
wchar_t yi[]=L"一二三四五六七八九十";
wchar_t ttt[1000];
wchar_t tttt[]=L";";
int count;
fp=fopen("d://2.txt","r");
fp2=fopen("d://1.txt","w");
k=0;
num=0;
formnum=0;
fprintf(fp2,"<?xml version='1.0' encoding='ISO-8859-1'?>\n<docunment>");
memset(temp,0,sizeof(temp));
memset(s,0,sizeof(s));
memset(form,0,sizeof(form));
while(fgets(s[k],1000,fp)!=NULL)//fgets原型:数组首地址,读入的元素个数,链接的文件
{
sum=0;
count=0;
s[k][strlen(s[k])-1]='\0';
for (i=0;i<strlen(s[k]);i++)//防止某一行全是空行
if (s[k][i]==' ')count++;
if ((strlen(s[k])-count)<=3)continue;
if (Find(s[k],'1')||Find(s[k],'2')||Find(s[k],'3')||Find(s[k],'4')||Find(s[k],'5')||Find(s[k],'6')||Find(s[k],'7')||Find(s[k],'8')||Find(s[k],'9'))
sum=sum+2;
mbstowcs(ttt,s[k],10000);
if (findchinese(ttt,yi))
sum=sum+4;
if (Find(s[k],':')||(findchinese(ttt,tttt)))
sum=sum+8;
if (sum==0)//如果不含有关键字符,那么只是普通段落
{
if (num==0)//如果是普通段落的第一行
fprintf(fp2,"\n<section>\n<maintext>");
strcpy(temp[num],s[k]);
num++;
}
else//如果含有关键字,则首先将保存的temp中的普通段落输出
{

for (i=0;i<num;i++)
fprintf(fp2,"%s\n",temp[i]);
if (num>0)fprintf(fp2,"</maintext>\n</section>\n");
num=0;
memset(temp,0,sizeof(temp));
if (find(form,num))//如果之前出现过该种格式,就输出</section>同时将这种格式删除
{
fprintf(fp2,"\n</section>\n");
formnum--;
}
else
{
//如果之前没有出现过这种格式,将这种格式记录下来
fprintf(fp2,"<section>");
fprintf(fp2,"%s",s[k]);
fprintf(fp2,"</section>\n");
form[formnum++]=sum;
}
}

}
for (i=0;i<num;i++)
fprintf(fp2,"%s",temp[i]);
num=0;
fprintf(fp2,"</maintext>\n</section>\n");
fprintf(fp2,"</docunment>");
fclose(fp);
fclose(fp2);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: