benim amaçlar için yazdığı filmor en cevabın bir versiyonudur. Biraz daha okunabilir, muhtemelen biraz daha yavaş. Ben her zaman char *
ile uğraştığım için şablon şeyler gerek yoktu ve benim durumumda ben ile Latin olmayan karakterleri değiştirmek istedim _. Her ihtimale karşı yardımcı olur birisi:
int GetUtf8CharacterLength(unsigned char utf8Char)
{
if (utf8Char < 0x80) return 1;
else if ((utf8Char & 0x20) == 0) return 2;
else if ((utf8Char & 0x10) == 0) return 3;
else if ((utf8Char & 0x08) == 0) return 4;
else if ((utf8Char & 0x04) == 0) return 5;
return 6;
}
char Utf8ToLatin1Character(char *s, int *readIndex)
{
int len = GetUtf8CharacterLength(static_cast<unsigned char>(s[ *readIndex ]));
if (len == 1)
{
char c = s[ *readIndex ];
(*readIndex)++;
return c;
}
unsigned int v = (s[ *readIndex ] & (0xff >> (len + 1))) << ((len - 1) * 6);
(*readIndex)++;
for (len-- ; len > 0 ; len--)
{
v |= (static_cast<unsigned char>(s[ *readIndex ]) - 0x80) << ((len - 1) * 6);
(*readIndex)++;
}
return (v > 0xff) ? 0 : (char)v;
}
// overwrites s in place
char *Utf8ToLatin1String(char *s)
{
for (int readIndex = 0, writeIndex = 0 ; ; writeIndex++)
{
if (s[ readIndex ] == 0)
{
s[ writeIndex ] = 0;
break;
}
char c = Utf8ToLatin1Character(s, &readIndex);
if (c == 0)
{
c = '_';
}
s[ writeIndex ] = c;
}
return s;
}
Testi kodu:
char s2[ 256 ] = "lif\xc3\xa9 is b\xc3\xa9tt\xc3\xa9r with acc\xc3\xa9nts";
Utf8ToLatin1String(s2);
UTF8 65536 kod noktalarını temsil edebilir; latin1 (ISO-8859-1) sadece 256'yı temsil edebilir. Dönüştürülemeyen tüm karakterlerle nasıl ilgilenmek istersiniz? – simonc
C'ye bu http://www.jamesmurty.com/2011/12/30/python-code-utf8-to-latin1/ (tüm sembollerin dönüştürülemeyeceğini unutmayın) –
@DavidRF koşulu " herhangi bir ekstra libs "verilen kodun son satırında olduğu gibi hazır fonksiyonların kullanılmaması anlamına gelir," utf8_text.encode ('ISO-8859-1', 'replace') ' – Dialecticus