2 votes

Utilisation de chaînes UTF-8 en C

Je suis en train d'écrire une extension native pour Adobe AIR en C. Le code devrait être porté sur d'autres plates-formes plus tard. Dans ma fonction du côté C, je reçois une chaîne de caractères de air comme ceci

uint32_t len;
const uint8_t * str = 0;
if( FRE_OK == FREGetObjectAsUTF8(argv[0], &len, &str) )
{
    // Ici, je dois passer une chaîne de caractères en argument à une autre fonction
    printf("Chaîne obtenue %s", str); // Affiche des caractères bizarres au lieu de str
}

FREGetObjectAsUTF8 renvoie une chaîne encodée en UTF8 qui devrait être représentée comme const uint8_t. Je travaille sur MacOS et XCode et uint8_t est défini comme unsigned char. Le problème se situe dans un ensemble de code C qui attend un simple char* en tant qu'argument. Je n'ai pas besoin de caractères unicode et n'utilise que des lettres latines et des chiffres.

J'ai essayé de caster un type sans succès. Par exemple

char buffer[512];
sprintf(buffer, "%s", (char*)str); // Mêmes caractères bizarres ici

Mais si je parcours la chaîne de caractères, j'obtiens la valeur correcte

for(i=0; i

`

Donc ma question est : Comment puis-je passer une chaîne UTF8 à une fonction qui attend un simple char signé ? En fait, je pourrais essayer de créer des fonctions en C++ et d'utiliser la partie C avec "extern", mais une solution purement en C serait plus préférable.

Je passe la chaîne "initapp" depuis air et si je la renvoie à l'exécution, elle m'affiche la valeur correcte "initapp". Dans mon code C, j'essaie de la passer à une fonction qui attend char* en argument

FREObject initApp(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[])
{
    uint32_t len;
    const uint8_t * str = 0;
    if( FRE_OK == FREGetObjectAsUTF8(argv[0], &len, &str) )
    {
        /*
        J'ai environ 40 fonctions et la plupart d'entre elles travaillent avec des chaînes ASCII
        */
        executeCommand( (const char*)str );
        FREObject result;
        FRENewObjectFromUTF8(len, str, &result);
        return result; // C'est correct. Chaîne correcte
    }
    return NULL;
}

Mais dans ma fonction, au lieu de "initapp", j'obtiens plusieurs caractères bizarres (différents à chaque fois) comme si j'essayais de sortir une partie d'une image ou une variable incorrecte.

Toute aide sera grandement appréciée.

`

2voto

bames53 Points 38303

Mac OS X attend généralement à ce que les chaînes char* simples soient en UTF-8 de toute façon, donc vous devriez obtenir des résultats corrects avec le code que vous avez montré.

sprintf(buffer, "%s", (char*)str);

Si du code comme celui-ci affiche des valeurs numériques indiquant une chaîne UTF-8 valide :

if( FRE_OK == FREGetObjectAsUTF8(argv[0], &len, &str) ) {
    for(int i=0; i

`

Et si remplacer la boucle printf par des appels à vos propres fonctions donne des résultats incorrects :

if( FRE_OK == FREGetObjectAsUTF8(argv[0], &len, &str) ) {
    executeCommand( (const char*)str );

    FREObject result;
    FRENewObjectFromUTF8(len, str, &result);
}

il y a probablement un problème avec executeCommand().

`

1voto

SigTerm Points 16055

Comment pourrais-je passer une chaîne utf8 à une fonction qui attend un simple char signé?

Deux façons de le faire:

  1. Il suffit de le caster en const char*. La chaîne utf8 est "compatible" avec la chaîne const char en ce sens que la chaîne C uniquement en ascii sera identique à la chaîne utf8 contenant uniquement des caractères ascii, et la chaîne utf8 avec des caractères non-ascii ne contiendra pas de zéros au milieu. Cependant, si vous utilisez cette méthode, tout caractère qui ne fait pas partie de l'ASCII se transformera en une séquence de caractères illisibles. Bien sûr, si la fonction C attend quelque chose comme un chemin d'accès de fichier pour ouvrir un fichier, cela ne fonctionnera pas.
  2. Utilisez des fonctions de texte spécifiques à l'OS qui vous permettent de changer de page de code et de ré-encoder la chaîne utf8 en la page de code 8 bits que votre système utilise. Cependant, en utilisant cette méthode, les caractères qui ne font pas partie de la page de code du système seront "perdus" - ils seront transformés en un caractère "par défaut" comme '?' ou "point d'interrogation dans un carré". Ainsi, quelque chose comme "étudier les caractères japonais" deviendra "étudier les ???". En guise d'alternative à la fonction OS, vous pourriez essayer d'utiliser quelque chose comme libiconv, mais cela ne résoudra pas le problème des "caractères non présents dans la page de code".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X