您需要使用单独的 utf-8 编码器。
在 snprintf() 中,您的文本采用 CP-1251(单字节 ASCII 时代编码),而不是 UTF-8(可变宽度编码)。
请参阅此链接以获取参考实现:http: //7maze.ru/node/29
评论是俄语的,但您只需要一个转换表和
string convertToUtf8(const char* chars, int len)
最后发挥作用。
您使用的“тест”字符串在编码时应该看起来像“РўРчС_С'”(绝对没有意义)。
来自一个旧项目的旧 C 代码。它使用 CP-866 编码(MS-DOS 的另一种“流行”编码),但从 CP-1251 转换很简单。
/// CP866 to UTF-8
char *dosstrtou(char *buffer,const char *dosstr)
{
char *buf1=buffer;
while (*dosstr)
{
if ( (*dosstr>127)&&(*dosstr<176) )
{
*buf1=208;
buf1++;
*buf1 = (char)(*dosstr+16);
dosstr++;
buf1++;
continue;
}
if ( (*dosstr>223)&&(*dosstr<240) )
{
*buf1=209;
buf1++;
*buf1 = (char)(*dosstr-96);
dosstr++;
buf1++;
continue;
}
if (*dosstr==240)
{
*buf1=208;
buf1++;
*buf1=129;
dosstr++;
buf1++;
continue;
}
if (*dosstr==241)
{
*buf1=209;
buf1++;
*buf1=145;
dosstr++;
buf1++;
}
*buf1=*dosstr;
buf1++;
dosstr++;
}
*buf1='\0';
return (buffer);
}
/// CP1251 to CP866
char *winstrtodos(char *buffer){
char *ptr=buffer;
while (*ptr!='\0')
{
if ( (*ptr>=0x80+0x40)&&(*ptr<=0xAF+0x40) )
*ptr =(char)(*ptr-0x40);
if ( (*ptr>=0xE0+0x10)&&(*ptr<=0xEF+0x10) )
*ptr = (char)(*ptr-0x10);
if (*ptr==0xA8) *ptr=0xF0;
if (*ptr==0xB8) *ptr=0xF1;
ptr++;
}
return (buffer);
}
只是要小心内存。