Como converter seqüência de caracteres Unicode em uma seqüência de utf-8 ou utf-16?

votos
6

Como converter seqüência de caracteres Unicode em uma seqüência de utf-8 ou utf-16? Meu projeto VS2005 está usando Unicode conjunto char, enquanto sqlite no cpp fornecem

int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
int sqlite3_open16(
  const void *filename,   /* Database filename (UTF-16) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);

para a abertura de uma pasta. Como posso converter corda, CString ou wstring em UTF-8 ou UTF-16 charset?

Muito obrigado!

Publicado 11/11/2008 em 09:38
fonte usuário
Em outras línguas...                            


5 respostas

votos
7

Resposta curta:

Nenhuma conversão necessária se usar cadeias de caracteres Unicode como CString ou wstring. Use sqlite3_open16 (). Você terá que certifique-se de passar um ponteiro WCHAR (escalado para void *. Parece coxo! Mesmo que essa lib é multi-plataforma, eu acho que eles poderiam ter definido uma ampla tipo char que depende da plataforma e é menos hostil do que um void *) para o API. Tal como para um CString:(void*)(LPCWSTR)strFilename

A resposta mais longa:

Você não tem uma seqüência de caracteres Unicode que você deseja converter para UTF8 ou UTF16. Você tem uma seqüência de caracteres Unicode representada em seu programa usando uma determinada codificação: Unicode não é uma representação binária per se. Codificações dizer como os pontos de código Unicode (valores numéricos) são representados na memória (de layout binária do número). UTF8 e UTF16 são as codificações mais utilizados. Eles são muito diferentes embora.

Quando um projeto VS diz "charset Unicode", que na verdade significa "caracteres são codificados como UTF16". Portanto, você pode usar sqlite3_open16 () diretamente. Nenhuma conversão necessário. Os caracteres são armazenados no tipo WCHAR (em oposição a char) que leva 16 bits (Fallsback do tipo C padrão wchar_t, o que leva 16 bits no Win32. Pode ser diferente em outras plataformas. Graças para a correcção, Damas).

Há mais um detalhe que você pode querer prestar atenção: UTF16 existe em 2 sabores: Big Endian e Little Endian. Essa é a ordenação de bytes destes 16 bits. O protótipo da função que você dá para UTF16 não diz que ordenação é usado. Mas você é bastante seguro assumir que sqlite usa o mesmo endian-ness como o Windows (Little Endian IIRC. Eu sei que a ordem, mas sempre tive problema com os nomes :-)).

EDIT: Resposta a comentar por Damas:

UTF16 utiliza 16 bits de unidades de código . Em Win32 (e única no Win32), wchar_té utilizado para tal unidade de armazenamento. O truque é que alguns caracteres Unicode requerem uma sequência de 2 tais unidades de código de 16 bits. Eles são chamados de pares substitutos.

Da mesma maneira uma UTF-8 representa um carácter usando uma sequência de 1 a 4 bytes. No entanto UTF8 são usados com o chartipo.

Respondeu 11/11/2008 em 10:38
fonte usuário

votos
7

Use o WideCharToMultiByte função. Especificar CP_UTF8para o CodePageparâmetro.

CHAR buf[256]; // or whatever
WideCharToMultiByte(
  CP_UTF8, 
  0, 
  StringToConvert, // the string you have
  -1, // length of the string - set -1 to indicate it is null terminated
  buf, // output
  __countof(buf), // size of the buffer in bytes - if you leave it zero the return value is the length required for the output buffer
  NULL,    
  NULL
);

Além disso, a codificação padrão para aplicativos Unicode no Windows é UTF-16LE, então você pode não precisar de realizar qualquer tradução e usar apenas a segunda versão sqlite3_open16.

Respondeu 11/11/2008 em 09:44
fonte usuário

votos
3

Todos o C ++ tipos string são charset neutro. Eles apenas se contentar em uma largura de carácter, e não fazer mais suposições. A wstring usa caracteres de 16 bits no Windows, o que corresponde aproximadamente a utf-16, mas ainda depende do que você armazenar no segmento. O wstring não de forma alguma impor que os dados que você colocar nele deve ser UTF16 válido. Windows usa UTF16 quando Unicode é definido embora, então provavelmente as cordas já estão UTF16, e você não precisa fazer nada.

Alguns outros têm sugerido usando a função WideCharToMultiByte, que é (uma das) caminho (s) para ir para converter UTF16 para utf8. Mas desde que sqlite pode lidar com UTF16, que não deve ser necessário.

Respondeu 11/11/2008 em 09:46
fonte usuário

votos
0

A maneira mais simples de fazer isso é usar CStringA. A classe CString é um typedef para qualquer CStringA (versão ASCII) ou CStringW (versão caractere de largura). Ambas essas classes têm construtores para converter tipos de cordas. Eu normalmente uso:

sqlite3_open(CStringA(L"MyWideCharFileName"), ...);
Respondeu 22/08/2014 em 22:56
fonte usuário

votos
0

utf-8 e UTF-16 são ambos "unicode" codificação de caracteres. O que você provavelmente falar é utf-32, que é uma codificação de caracteres de tamanho fixo. Talvez procurando

"Convert utf-32 into utf-8 or utf-16"

fornece-lhe alguns resultados ou outros documentos sobre este assunto.

Respondeu 11/11/2008 em 09:44
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more