Pergunta

Eu estou escrevendo um pequeno wrapper para um aplicativo que arquivos usa como argumentos.

As necessidades de mensagens publicitárias para a Unicode, por isso estou usando wchar_t para os personagens e cordas eu tenho. Agora eu me encontro em um problema, eu preciso ter os argumentos do programa em uma matriz de wchar_t de e em uma string wchar_t.

É possível? Eu estou definindo a função main como

int main(int argc, char *argv[])

Devo usar wchar_t é para argv?

Muito obrigado, eu não parecem encontrar informações úteis sobre como utilizar Unicode corretamente no C.

Foi útil?

Solução

Em geral, não. Vai depender o O / S, mas o padrão C diz que os argumentos para 'principal ()' deve ser 'principal (int argc, char ** argv)' ou equivalente, de modo a não ser que de char e wchar_t são o mesmo tipo de base , você não pode fazê-lo.

Dito isto, você poderia começar UTF-8 cordas argumento para o programa, convertê-los em UTF-16 ou UTF-32, e depois seguir com a vida.

Em um Mac (10.5.8, Leopard), eu tenho:

Osiris JL: echo "ï€" | odx
0x0000: C3 AF E2 82 AC 0A                                 ......
0x0006:
Osiris JL: 

Isso é tudo UTF-8 codificado. (Odx é um programa hexadecimal).

Veja também: Por que é que a codificação UTF-8 é usado quando interagindo com um ambiente UNIX / Linux

Outras dicas

código portátil não apoiá-lo. Windows (por exemplo) suporta usando wmain vez de main, caso em que argv é passado como caracteres largos.

No Windows, você pode usar GetCommandLineW() e CommandLineToArgvW() para produzir uma variedade wchar_t[] de estilo argv, mesmo que o aplicativo não é compilado para Unicode.

No Windows de qualquer maneira, você pode ter um wmain() para Unicode cria. embora não portátil. Eu não sei se as plataformas do CCG ou Unix / Linux fornecer qualquer coisa similar.

Assumindo que o seu ambiente Linux utiliza codificação UTF-8, em seguida, o seguinte código irá preparar o seu programa para facilitar o tratamento Unicode em C ++:

    int main(int argc, char * argv[]) {
      std::setlocale(LC_CTYPE, "");
      // ...
    }

Em seguida, tipo wchar_t é de 32 bits no Linux, o que significa que ele pode conter pontos de código individuais Unicode e você pode usar com segurança wstring tipo para processamento seqüência clássica em C ++ (caractere por caractere). Com chamada setlocale acima, inserindo wcout irá traduzir automaticamente a sua saída em UTF-8 e extrair wcin irá traduzir automaticamente a entrada UTF-8 em UTF-32 (1 caracter = 1 ponto de código). O único problema que resta é que argv [i] cordas são ainda UTF-8 codificado.

Você pode usar a seguinte função para decodificar UTF-8 em UTF-32. Se a cadeia de entrada está corrompido ele irá retornar caracteres adequadamente convertidos até o lugar onde as regras UTF-8 foram quebrados. Você poderia melhorá-lo se precisar de mais relatórios de erro. Mas para argv dados pode-se seguramente assumir que ele está correto UTF-8:

#define ARR_LEN(x) (sizeof(x)/sizeof(x[0]))

    wstring Convert(const char * s) {
        typedef unsigned char byte;
        struct Level { 
            byte Head, Data, Null; 
            Level(byte h, byte d) {
                Head = h; // the head shifted to the right
                Data = d; // number of data bits
                Null = h << d; // encoded byte with zero data bits
            }
            bool encoded(byte b) { return b>>Data == Head; }
        }; // struct Level
        Level lev[] = { 
            Level(2, 6),
            Level(6, 5), 
            Level(14, 4), 
            Level(30, 3), 
            Level(62, 2), 
            Level(126, 1)
        };

        wchar_t wc = 0;
        const char * p = s;
        wstring result;
        while (*p != 0) {
            byte b = *p++;
            if (b>>7 == 0) { // deal with ASCII
                wc = b;
                result.push_back(wc);
                continue;
            } // ASCII
            bool found = false;
            for (int i = 1; i < ARR_LEN(lev); ++i) {
                if (lev[i].encoded(b)) {
                    wc = b ^ lev[i].Null; // remove the head
                    wc <<= lev[0].Data * i;
                    for (int j = i; j > 0; --j) { // trailing bytes
                        if (*p == 0) return result; // unexpected
                        b = *p++;   
                        if (!lev[0].encoded(b)) // encoding corrupted
                            return result;
                        wchar_t tmp = b ^ lev[0].Null;
                        wc |= tmp << lev[0].Data*(j-1);
                    } // trailing bytes
                    result.push_back(wc);
                    found = true;
                    break;
                } // lev[i]
            }   // for lev
            if (!found) return result; // encoding incorrect
        }   // while
        return result;
    }   // wstring Convert

No Windows, você pode usar tchar.h e _tmain, que será transformado em wmain se o símbolo _UNICODE é definido em tempo de compilação, ou principal de outra forma. TCHAR * argv [] será igualmente ser expandido para WCHAR * argv [] se Unicode é definido, e char * argv [], se não.

Se você quer ter a sua plataforma de trabalho método cross principal, você pode definir suas próprias macros para o mesmo efeito.

Tchar.h contém um número de macros de conveniência para a conversão entre wchar e carvão animal.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top