Aquí es una versión de la respuesta de filmor que escribí para mis propósitos. Un poco más legible, probablemente un poco más lento. No necesitaba las plantillas, ya que siempre me ocupé del char *
, y en mi caso quería reemplazar caracteres no latinos con _. Sólo en caso de que ayuda a alguien:
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;
}
Código de ensayo:
char s2[ 256 ] = "lif\xc3\xa9 is b\xc3\xa9tt\xc3\xa9r with acc\xc3\xa9nts";
Utf8ToLatin1String(s2);
UTF8 puede representar 65.536 puntos de código; latin1 (ISO-8859-1) solo puede representar 256. ¿Cómo desea tratar con todos los caracteres que no se pueden convertir? – simonc
Puede traducir a C este http://www.jamesmurty.com/2011/12/30/python-code-utf8-to-latin1/ (tenga en cuenta que no todos los símbolos se pueden convertir) –
condición @DavidRF "sin usar cualquier libs extra "significa no usar funciones preparadas como en la última línea del código dado,' utf8_text.encode ('ISO-8859-1', 'reemplazar') ' – Dialecticus