■ Unicode/UTF-8 相互変換
/*
* utf8.c : Unicode <-> UTF-8 相互変換
*
* Copyright (c) 2004 AOK.
*
* 2004.07.14 - 初版
*
* UCS-2 UTF-8
* 0000-007F 0xxxxxxx
* 0080-07FF 110xxxxx 10xxxxxx
* 0800-FFFF 1110xxxx 10xxxxxx 10xxxxxx
*
*/
#include <stdio.h>
#include <stdlib.h>
unsigned long _to_utf8(const unsigned short *s, unsigned char *d)
{
long c = 0;
while (*s != 0) {
if (*s <= 0x7f) {
if (d != NULL) *d++ = *s;
c++;
} else if (*s >= 0x80 && *s <= 0x7ff) {
if (d != NULL) {
*d++ = ((*s >> 6) & 0x1f) | 0xc0;
*d++ = (*s & 0x3f) | 0x80;
}
c += 2;
} else {
if (d != NULL) {
*d++ = (*s >> 12) | 0xe0;
*d++ = ((*s >> 6) & 0x3f) | 0x80;
*d++ = (*s & 0x3f) | 0x80;
}
c += 3;
}
s++;
}
if (d != NULL) *d = 0;
return c;
}
unsigned long _from_utf8(const unsigned char *s, unsigned short *d)
{
long c = 0;
int flag = 0;
unsigned short tmp;
while (*s != 0) {
if (flag == 0) {
if ((*s & 0xe0) == 0xe0) {
flag = 2;
tmp = (*s & 0x0f) << 12;
} else if ((*s & 0xc0) == 0xc0) {
flag = 1;
tmp = (*s & 0x1f) << 6;
} else if ((*s & 0x80) == 0) {
if (d != NULL) *d++ = *s;
c++;
} else {
flag = 0;
}
} else if (flag == 1) {
flag = 0;
if (d != NULL) *d++ = tmp | (*s & 0x3f);
c++;
} else if (flag == 2) {
flag = 3;
tmp |= (*s & 0x3f) << 6;
} else if (flag == 3) {
flag = 0;
if (d != NULL) *d++ = tmp | (*s & 0x3f);
c++;
} else {
flag = 0;
}
s++;
}
if (d != NULL) *d = 0;
return c;
}
/* メイン */
int main()
{
unsigned short s[] = {
0x30AB, 0x30CA, 0x30C0, 0x304B, 0x3089,
0x306E, 0x0032, 0x901A, 0x306E, 0x624B,
0x7D19, 0,
};
unsigned char *d;
unsigned long i, c;
c = _to_utf8(s, NULL);
d = (unsigned char *)malloc(sizeof(unsigned char)*(c+1));
_to_utf8(s, d);
printf("UTF-8: ");
for (i = 0; i <= c; i++) printf("%02X ", *(d+i));
putchar('\n');
printf("UTF-16: ");
c = _from_utf8(d, s);
for (i = 0; i <= c; i++) printf("%04X ", s[i]);
putchar('\n');
free(d);
return 0;
}