9
votes

C ++ Comment inspecter la note de commande d'octets de fichier afin d'obtenir s'il est UTF-8?

Je me demande comment inspecter la marque de commande d'octet de fichier afin d'obtenir s'il est UTF-8 en C ++?


5 commentaires

Quelle est la solution? Tout ce que vous avez à faire est de le comparer à 0xef, 0xbb, 0xbf. Je pense que vous devez donner plus de détails sur votre problème.


Cela pourrait être d'une certaine pertinence: en.wikipedia.org/wiki/byte_order_mark#UTF-8


La même chose que vous faites dans n'importe quelle langue. Vous obtenez les trois premiers octets. S'ils ressemblent aux octets UTF-8 pour la marque d'ordre d'octet Unicode, alors c'est UTF-8. S'ils ne le font pas, alors ce n'est pas le cas. Demandez-vous que quelqu'un écrit le code source pour vous?


Nicol - "S'ils ne le font pas, ce n'est pas" - pas vrai. S'ils ne ressemblent pas à un bom, il pourrait très facilement être utf-8 encore. Il n'y a pas besoin de marque d'ordre d'octet avec codage UTF-8.


@Nicol vous suggère de supprimer ou d'éditer ce commentaire car c'est faux. Une séquence d'octets qui ressemblent à un bom unicode ne vous indique que cela peut être des données unicode. Cela pourrait signifier "ï" ¿".


4 Réponses :


5
votes

0XEF, 0xbb, 0xbf

Commander ne dépend pas de l'endansion.

Comment vous lisez le fichier avec C ++ est à vous de vous. Personnellement, j'utilise toujours les méthodes de fichier de style c-style C, car ils sont fournis par la bibliothèque, je codis avec et je peux être sûr de spécifier au mode binaire et d'éviter les traductions non invitées dans la ligne. < P> Adapté de CS.vt.edu < Pré> xxx

Alternativement, de nombreux formats utilisent UTF-8 par défaut si aucun autre bom (UTF-16 ou UTF-32, par exemple, par exemple) n'est spécifié.

wiki pour bom

unicode.org.faq


0 commentaires

12
votes

En général, vous ne pouvez pas.

La présence d'une marque d'ordre d'octet est une indication très forte que le fichier que vous lisez est Unicode. Si vous attendez un fichier texte et que les quatre premiers octets que vous recevez sont les suivants: P>

0x00, 0x00, 0xfe, 0xff -- The file is almost certainly UTF-32BE
0xff, 0xfe, 0x00, 0x00 -- The file is almost certainly UTF-32LE
0xfe, 0xff,  XX,   XX     -- The file is almost certainly UTF-16BE
0xff, 0xfe,  XX,   XX (but not 00, 00) -- The file is almost certainly UTF-16LE
0xef, 0xbb, 0xbf,  XX   -- The file is almost certainly UTF-8 With a BOM


2 commentaires

Est-ce que le "(mais pas 00, 00)" s'applique à l'UTF-16BE et UTF-16LE, ou juste à celui-ci?


FE FF 00 00 serait UTF16-BE, NOT UTF32. Dans UTF-32, il représenterait U + FFFE, qui est un non-caractère et ne devrait être présent dans aucun document Unicode. Dans UTF-16BE, c'est un bom suivi d'un personnage null



5
votes
if (buffer[0] == '\xEF' && buffer[1] == '\xBB' && buffer[2] == '\xBF') {
    // UTF-8
}
It's better to use buffer[0] == '\xEF' instead of buffer[0] == 0xEF in order to avoid signed/unsigned char problems, see How do I represent negative char values in hexadecimal?

1 commentaires

J'ai dû utiliser une combinaison d'ifstream.Lead (..) (pas d'obtenir ()) et le charcuter littéral pour que les octets de la naissance soient appariés. À votre santé!



2
votes

Ceci est ma version en C ++:

#include <fstream>

/* Reads a leading BOM from file stream if it exists.
 * Returns true, iff the BOM has been there. */
bool ReadBOM(std::ifstream & is)
{
  /* Read the first byte. */
  char const c0 = is.get();
  if (c0 != '\xEF') {
    is.putback(c0);
    return false;
  }

  /* Read the second byte. */
  char const c1 = is.get();
  if (c1 != '\xBB') {
    is.putback(c1);
    is.putback(c0);
    return false;
  }

  /* Peek the third byte. */
  char const c2 = is.peek();
  if (c2 != '\xBF') {
    is.putback(c1);
    is.putback(c0);
    return false;
  }

  return true; // This file contains a BOM for UTF-8.
}


0 commentaires