¿Cómo saber si el texto en el portapapeles de Windows es ISO 8859 o UTF-8 en C ++?
Pregunta
Me gustaría saber si hay una manera fácil de detectar si el texto en el portapapeles está en ISO 8859 o UTF-8?
Aquí está mi código actual:
COleDataObject obj;
if (obj.AttachClipboard())
{
if (obj.IsDataAvailable(CF_TEXT))
{
HGLOBAL hmem = obj.GetGlobalData(CF_TEXT);
CMemFile sf((BYTE*) ::GlobalLock(hmem),(UINT) ::GlobalSize(hmem));
CString buffer;
LPSTR str = buffer.GetBufferSetLength((int)::GlobalSize(hmem));
sf.Read(str,(UINT) ::GlobalSize(hmem));
::GlobalUnlock(hmem);
//this is my string class
s->SetEncoding(ENCODING_8BIT);
s->SetString(buffer);
}
}
}
Solución
Consulte la definición de CF_LOCALE en esta página de Microsoft . Le indica la configuración regional del texto en el portapapeles. Mejor aún, si usas CF_UNICODETEXT en su lugar, Windows se convertirá a UTF-16 para ti.
Otros consejos
UTF-8 tiene una estructura definida para bytes que no son ASCII. Puede escanear en busca de bytes > = 128, y si se detecta alguno, verifique si forman una cadena UTF-8 válida.
Los formatos de bytes UTF-8 válidos se pueden encontrar en Wikipedia :
Unicode Byte1 Byte2 Byte3 Byte4
U+000000-U+00007F 0xxxxxxx
U+000080-U+0007FF 110xxxxx 10xxxxxx
U+000800-U+00FFFF 1110xxxx 10xxxxxx 10xxxxxx
U+010000-U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
respuesta anterior:
No tiene que hacerlo: todo el texto ASCII es válido en UTF-8, por lo que puede decodificarlo como UTF-8 y funcionará como se esperaba.
Para probar si contiene caracteres que no son ASCII, puede buscar bytes > = 128.
Puedo equivocarme, pero creo que no puede hacerlo: si abro un archivo UTF-8 sin Bom en mi editor, se muestra de forma predeterminada como ISO-8859-1 (mi ubicación), y al lado de un uso extraño de caracteres acentuados extranjeros (para mí), no tengo una pista visual sólida de que sea UTF-8 (a menos que esté codificado de otra manera en otro lugar, por ejemplo, declaración de juego de caracteres en HTML o XML): es un texto Ansi perfectamente válido.
John escribió " todo el texto ASCII es válido en UTF-8 " pero lo contrario es cierto.
Windows XP + utiliza naturalmente UTF-16, y tiene un formato de portapapeles para él, pero AFAIK simplemente ignora UTF-8, sin ningún tratamiento especial para él.
(Bueno, hay una API para convertir UTF-8 a UTF-16 (o Ansi, etc.), en realidad).
Puede consultar para ver obj.IsDataAvailable (CF_UNICODETEXT) para ver si hay disponible una versión Unicode de lo que está en el portapapeles.
-Adam