使用C语言计算utf-8字符串长度
2015-07-23 15:01
423 查看
C或C++语言处理宽字节字符串上是个弱项,虽然stl定义了wstring等类型,但是实际应用中还是存在一些问题,而C语言的支持就更少了,如果想跨平台,问题就会更多。
最近项目中要处理utf-8字符串,需要计算字符串长度以及对其裁剪,例子代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//utf8字符长度1-6,可以根据每个字符第一个字节判断整个字符长度
//0xxxxxxx
//110xxxxx10xxxxxx
//1110xxxx 10xxxxxx10xxxxxx
//11110xxx 10xxxxxx10xxxxxx 10xxxxxx
//111110xx 10xxxxxx10xxxxxx 10xxxxxx 10xxxxxx
//1111110x 10xxxxxx10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
//
//定义查找表,长度256,表中的数值表示以此为起始字节的utf8字符长度
unsigned char utf8_look_for_table[]=
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
};
#define UTFLEN(x) utf8_look_for_table[(x)]
//计算str字符数目
int getUtf8Length(char *str)
{
int clen= strlen(str);
int len= 0;
for(char *ptr =str;
*ptr!=0&&len<clen;
len++, ptr+=UTFLEN((unsigned char)*ptr));
return len;
}
//get子串
char*subUtfString(char *str, unsigned int start, unsigned int end)
{
int len= getUtf8Length(str);
if(start>= len) return NULL;
if(end> len) end = len;
char *sptr =str;
for(int i= 0;i < start; ++i,sptr+=UTFLEN((unsigned char)*sptr));
char *eptr =sptr;
for(int i = start;i < end; ++i,eptr += UTFLEN((unsigned char)*eptr));
int retLen =eptr - sptr;
char *retStr =(char*)malloc(retLen+1);
memcpy(retStr, sptr,retLen);
retStr[retLen] = 0;
return retStr;
}
int main()
{
char *str= "我的a测试工具阿斯顿aaab123阿斯顿个流氓了卡斯!";
printf("%s\n", str);
for(char *ptr=str;*ptr!=0;) {
unsigned char c =(unsigned char)*ptr;
printf("str[%d] is a word character with %dbytes\n",c, UTFLEN(c));
ptr += UTFLEN(c);
}
printf("%d\n", getUtf8Length(str));
char *sub= subUtfString(str, 2, 100);
if(sub) {
printf("%s\n", sub);
free(sub);
sub = NULL;
}
return 0;
}
程序在osx下调试通过。
在vs2005下,默认的文件编码格式是gb2312,需要将文件保存成utf8格式。
原文地址:http://blog.sina.com.cn/s/blog_62b2318d0101d7kb.html
最近项目中要处理utf-8字符串,需要计算字符串长度以及对其裁剪,例子代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//utf8字符长度1-6,可以根据每个字符第一个字节判断整个字符长度
//0xxxxxxx
//110xxxxx10xxxxxx
//1110xxxx 10xxxxxx10xxxxxx
//11110xxx 10xxxxxx10xxxxxx 10xxxxxx
//111110xx 10xxxxxx10xxxxxx 10xxxxxx 10xxxxxx
//1111110x 10xxxxxx10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
//
//定义查找表,长度256,表中的数值表示以此为起始字节的utf8字符长度
unsigned char utf8_look_for_table[]=
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
};
#define UTFLEN(x) utf8_look_for_table[(x)]
//计算str字符数目
int getUtf8Length(char *str)
{
int clen= strlen(str);
int len= 0;
for(char *ptr =str;
*ptr!=0&&len<clen;
len++, ptr+=UTFLEN((unsigned char)*ptr));
return len;
}
//get子串
char*subUtfString(char *str, unsigned int start, unsigned int end)
{
int len= getUtf8Length(str);
if(start>= len) return NULL;
if(end> len) end = len;
char *sptr =str;
for(int i= 0;i < start; ++i,sptr+=UTFLEN((unsigned char)*sptr));
char *eptr =sptr;
for(int i = start;i < end; ++i,eptr += UTFLEN((unsigned char)*eptr));
int retLen =eptr - sptr;
char *retStr =(char*)malloc(retLen+1);
memcpy(retStr, sptr,retLen);
retStr[retLen] = 0;
return retStr;
}
int main()
{
char *str= "我的a测试工具阿斯顿aaab123阿斯顿个流氓了卡斯!";
printf("%s\n", str);
for(char *ptr=str;*ptr!=0;) {
unsigned char c =(unsigned char)*ptr;
printf("str[%d] is a word character with %dbytes\n",c, UTFLEN(c));
ptr += UTFLEN(c);
}
printf("%d\n", getUtf8Length(str));
char *sub= subUtfString(str, 2, 100);
if(sub) {
printf("%s\n", sub);
free(sub);
sub = NULL;
}
return 0;
}
程序在osx下调试通过。
在vs2005下,默认的文件编码格式是gb2312,需要将文件保存成utf8格式。
原文地址:http://blog.sina.com.cn/s/blog_62b2318d0101d7kb.html
相关文章推荐
- C++之带有默认参数值的构造函数
- 将一个正整数转换成2进制并输出
- C++异常处理学习记录
- C++中内置变量的初始化
- c语言优先级
- c++ iterator(迭代器)分类及其使用
- C++ map的使用
- C++ 虚函数、纯虚函数、继承、虚表、多态原理相关知识点总结
- C++控制台通迅录系统,实现文件同步更新
- c语言课程设计
- Java程序员学习C++之函数指针
- Java程序员学习C++之函数
- 黑马程序员_C语言基础_构造类型(数组,结构体,枚举)
- C++那些细节--中operator=相关问题
- C++模板特化
- java与 C++ 之间进行 SOCKET 通信
- 【Eclipse】Eclipse C++ MINGW :The program file specified in the launch configuration does not exist
- c语言 求两个整数的最大公约数
- C语言自学笔记
- c语言 计算三角形的面积