9
votes

Comment convertir UTF-8 en ASCII en C ++?

Je reçois la réponse du serveur dans UTF-8 mais ne pouvant pas la lire. Comment convertir UTF-8 en ASCII en C ++?

c++

6 commentaires

Est-ce que tous les personnages sont des caractères Single-Byte ASCII?


Je ne sais pas. Je ne sais que cette réponse est dans utf-8


Quel "serveur" est-ce? Êtes-vous sûr que les données ne sont pas zippées ou quelque chose?


@user: alors vous ne pouvez pas le faire. Il n'est pas possible de coder en ASCII autant que dans UTF8.


@Mike: la réponse est dans les paquets SOAP


Si, par exemple. Vous aimez écrire des caractères chinois en ASCII, vous devriez rechercher une translittération (c'est pourquoi j'ai trouvé ce post)


9 Réponses :


0
votes

utf-8 est à l'envers Compatible avec ASCII Signification Toutes les caractères ASCII sont codés sous forme de valeurs d'octets non modifiées dans UTF-8. Si le texte doit être ASCII, mais vous ne pouvez pas le lire, il doit y avoir un autre problème.


0 commentaires

4
votes

UTF-8 est un codage qui peut mapper chaque caractère Unicode. ASCII prend uniquement en charge un très petit sous-ensemble d'Unicode.

Pour le sous-ensemble d'UNICODE qui est ASCII, le mappage de UTF-8 à ASCII est un mappage d'octets d'une-à-un directe, de sorte que le serveur vous envoie un document ne contient que des caractères ASCII dans l'encodage UTF-8, puis Vous pouvez directement lire cela comme ASCII.

Si la réponse contient des caractères non-ASCII, tout ce que vous faites, vous ne pourrez pas les exprimer en ASCII. Pour les filtrer sur un flux UTF-8, vous pouvez simplement filtrer n'importe quel octet> = 128 (0x80 hexagonal).


3 commentaires

"Pour les filtrer sur un flux UTF-8, vous pouvez simplement filtrer n'importe quel octet> = 128 (0x80 hexagonal)" Bien sûr, cela détruira irrévocablement vos données.


@ Jörg W Mittag: Oui, j'aurais pensé que cela était aveuglément évident de la description du processus, cependant.


devrait . Mais de ma propre expérience essayant de remplir des formulaires sur des sites Web, je peux vous dire: ce n'est pas le cas. Hier, j'ai remarqué que mon nom était détruit quand eBay l'Allemagne a transmis mon nom à Allemand Service postal. Je veux dire, allez!



24
votes

Notez d'abord que ASCII est un format 7 bits. Il y a des codages 8 bits, si vous êtes après l'un d'entre eux (tel que ISO 8859-1), vous devrez être plus précis.

Convertir une chaîne ASCII en UTF-8, ne faites rien: ils sont les mêmes. Donc, si votre chaîne UTF-8 est composée uniquement de caractères ASCII, il s'agit déjà d'une chaîne ASCII, et aucune conversion n'est nécessaire.

Si la chaîne UTF-8 contient des caractères non-ASCII (rien avec des accents ou des caractères non latins), il n'y a aucun moyen de le convertir en ASCII. (Vous pourrez peut-être le convertir à l'un des codages ISO peut-être.)

Il existe des moyens de dépouiller les accents des caractères latins pour obtenir au moins une certaine ressemblance en ASCII. Alternativement si vous voulez simplement supprimer les caractères non-ASCII, supprimez simplement tous les octets avec des valeurs> = 128 de la chaîne UTF-8.


0 commentaires

5
votes

Si la chaîne contient des caractères qui n'existent pas en ASCII, il n'y a rien de vous peut faire, car, bien, ces caractères n'existent pas dans ASCII.

Si la chaîne contient seuls les caractères que sont existent en ASCII, alors il n'y a rien de vous besoin à faire, car la chaîne est < EM> Déjà dans le codage ASCII: UTF-8 a été spécialement conçu pour être compatible avec ASCII de telle sorte que tout caractère qui se trouve dans ASCII a exactement le même codage dans UTF-8 que dans ASCII. et que tout personnage qui est pas in ASCII peut jamais avoir un codage qui est valide ASCII, c'est-à-dire toujours avoir un codage qui est illégal En ASCII (plus précisément, tout caractère non ASCII sera codé en tant que séquence de 2-4 octets, tous les bits les plus importants, c'est-à-dire avoir une valeur entière> 127).

au lieu d'essayer simplement de convertir la chaîne, vous pouvez essayer de translittérate la chaîne. La plupart des langues de cette planète ont une forme de schéma de translittération ASCII qui conserve au moins le texte quelque peu compréhensible. Par exemple, mon prénom est "Jörg" et sa translittération ASCII serait "Joerg". Le nom du créateur du langage de programmation Ruby est "まつも と" et sa translittération ASCII serait "Matsumoto Yukihiroo". Cependant, veuillez noter que vous sera perdre des informations. Par exemple, la SZ-Ligature allemande est translittalitée à "SS", de sorte que le mot "maße" (mesures) devient translittéré à "Masse". Cependant, "Masse" (masse, dans le sens du physicien, pas le chrétien) est aussi un mot. Comme un autre exemple, turcs a 4 "I" S (petit et capitale, avec et sans points) et ASCII n'a que 2 (petit avec points et capitaux sans points), vous perdrez donc des informations sur le point ou si était une lettre majuscule.

Alors, le seul quels qui ne perdra pas d'informations (en d'autres termes: Données corrompues), est d'en quelque sorte encoder les caractères non-ASCII en séquences de caractères ASCII . Il existe de nombreux schémas de codage populaires: Références d'entité SGML, MIME, Séquences d'échappement Unicode, τ ε χ ou Laτ ε χ. Donc, vous encoderiez les données car il entre dans votre système et le décoderait quand il quitte le système.

Bien sûr, la méthode la plus simple serait de réparer simplement votre système.


0 commentaires

0
votes

ASCII est un codépage représentant 128 caractères et des codes de contrôle où, comme UTF8 est capable de représenter n'importe quel caractère de la norme UNICODE qui est beaucoup plus importante aux capacités ASCII. Alors répondez à votre question est la suivante: non possible Sauf si vous avez plus de spécification pour la source de données.


0 commentaires

1
votes

Vérifiez cette bibliothèque de chaînes UTF-8 , oubliez la conversion en ASCII.


0 commentaires

12
votes

Cet exemple fonctionne sous Windows (vous n'avez pas mentionné votre système d'exploitation cible): xxx

N'oubliez pas de Suppr [] large; et / ou ANSI quand n'est plus nécessaire. Comme il s'agit d'unicode, je recommanderais de rester à wchar_t * au lieu de char * sauf si vous êtes certain que la mémoire tampon d'entrée contient des caractères appartenant au même sous-ensemble ANSI. < / p>


2 commentaires

Cela a fonctionné sur Windows 7 mais n'a pas fonctionné sur XP-intégré.


Probablement parce que XpEndded ne vient pas avec le CodePage US-ASCII (20127) installé par défaut. Nous avons couru aussi dans ça.



-3
votes

sur la phrase

"Si la chaîne contient des caractères qui n'existent pas dans ASCII, il n'y a rien que vous puissiez faire, car, bien, ces personnages n'existent pas en ASCII."

C'est faux.

utf-8 est défini sur le code multibyte et peut prendre plus de 2 séries de symboles (langues). Pratiquement, vous avez soit une langue unique (anglais comme d'habitude) ou 2 langues que l'une d'entre elles est l'anglais.

  • Le premier cas est simple d'ASCII CHAR (tout codage).
  • Le second décrit le codage correspondant de l'ASCII. Si ce n'est pas chinois ou arabe.

    Dans les conditions ci-dessus, vous pouvez convertir UTF-8 en caractères ASCII. Fonctionnel correspondant, il n'y a pas de C ++. Donc, vous pouvez le faire manuellement. Il est facile de détecter deux symboles d'octets de 1 octet. Le bit élevé du premier octet est défini pour deux octets et non défini autrement.


0 commentaires

1
votes

Notez qu'il existe deux types utf8 code> types: utf8_with_bom kbd> et utf8_without_bom kbd>. Et vous devez gérer différemment pour eux en convertir en ansi code>. Les fonctions suivantes fonctionneront.

  • utf8_with_bom kbd> à ansi kbd> p>

    void change_encoding_from_UTF8_without_BOM_to_ANSI(const char* filename)
    {
        ifstream infile;
        string strLine="";
        string strResult="";
        infile.open(filename);
        if (infile)
        {
            while(!infile.eof())
            {
                getline(infile, strLine);
                strResult += strLine+"\n";
            }
        }
        infile.close();
    
        char* changeTemp=new char[strResult.length()];
        strcpy(changeTemp, strResult.c_str());
        char* changeResult = change_encoding_from_UTF8_to_ANSI(changeTemp);
        strResult=changeResult;
    
        ofstream outfile;
        outfile.open(filename);
        outfile.write(strResult.c_str(),strResult.length());
        outfile.flush();
        outfile.close();
    }
    
  • utf8_without_bom kbd> à ansi kbd> p>

    void change_encoding_from_UTF8_with_BOM_to_ANSI(const char* filename)
    {
        ifstream infile;
        string strLine="";
        string strResult="";
        infile.open(filename);
        if (infile)
        {
            // the first 3 bytes (ef bb bf) is UTF-8 header flags
            // all the others are single byte ASCII code.
            // should delete these 3 when output
            getline(infile, strLine);
            strResult += strLine.substr(3)+"\n";
    
            while(!infile.eof())
            {
                getline(infile, strLine);
                strResult += strLine+"\n";
            }
        }
        infile.close();
    
        char* changeTemp=new char[strResult.length()];
        strcpy(changeTemp, strResult.c_str());
        char* changeResult = change_encoding_from_UTF8_to_ANSI(changeTemp);
        strResult=changeResult;
    
        ofstream outfile;
        outfile.open(filename);
        outfile.write(strResult.c_str(),strResult.length());
        outfile.flush();
        outfile.close();
    }
    
    // change a char's encoding from UTF8 to ANSI
    char* change_encoding_from_UTF8_to_ANSI(char* szU8)
    { 
        int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0);
        wchar_t* wszString = new wchar_t[wcsLen + 1];
        ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen);
        wszString[wcsLen] = '\0';
    
        int ansiLen = ::WideCharToMultiByte(CP_ACP, NULL, wszString, wcslen(wszString), NULL, 0, NULL, NULL);
        char* szAnsi = new char[ansiLen + 1];
        ::WideCharToMultiByte(CP_ACP, NULL, wszString, wcslen(wszString), szAnsi, ansiLen, NULL, NULL);
        szAnsi[ansiLen] = '\0';
    
        return szAnsi;
    }
    


0 commentaires