9
votes

Ignorer les marques d'ordre d'octet en C ++, lecture d'un flux

J'ai une fonction pour lire la valeur d'une variable (entier, double ou booléen) sur une seule ligne dans un ifstream : xxx

Toutefois, Il échoue sur des fichiers texte créés avec des éditeurs insérant un bom ( note de commande d'octet ) au début de la première ligne, qui inclut malheureusement {note, mot} tampon. Comment puis-je modifier cette fonction pour ignorer la marque de commande d'octet si présente au début de str ?


2 commentaires

Vous voulez dire la naissance UTF-8? C'est très arcanique ...


Ahem .. UTF8 BOM n'est pas FEFF EF BB BB BF, il est censé être endian agnostique aussi. BTW Le BOM UTF8 est cacacé par le consortium Unicode.


3 Réponses :


4
votes

Vous devez commencer par lire le premier octet ou deux du flux, et décider si cela fait partie d'une chômée ou non. C'est un peu douloureux, puisque vous ne pouvez que putback un seul octet, alors que vous le ferez généralement vouloir lire quatre. La solution la plus simple consiste à ouvrir le fichier, à lire la octets initiaux, mémorisez combien vous devez sauter, puis chercher à la commencer et les sauter.


4 commentaires

La nomenclature UTF8 est trois octets longtemps. Je suppose que le flux est d'octet, car il s'agit d'un Char -Stream, il ne peut donc pas vraiment être utf16 ou utf32.


@Kerreksb Vous pouvez lire UTF-16 et UTF-32 comme des flux Char , à condition que vous disposiez des paramètres régionaux appropriés. D'autre part, je ne sais pas ce qu'ils feraient avec un bom. (IMHO, la nomination devrait vraiment être la responsabilité du flux. Ou plutôt du codecvt facette utilisée.)


J'avais oublié les locaux. Devez-vous écrire le vôtre ou existe-t-il un UTF-16 dans la norme?


@Kerreksb Le seul local dans la norme est "C". Pour le reste, tout dépend de la mise en œuvre. Pour Linux, vous pouvez voir ce que sont disponibles dans la liste / usr / lib / locale . Je ne connais cependant aucun équivalent pour Windows.



15
votes

(Je suppose que vous êtes sous Windows, car vous utilisez U + FeFF comme une signature dans les fichiers UTF-8 est surtout une chose de Windows et doit simplement être évitée ailleurs)

Vous pouvez ouvrir le fichier comme un UTF -8 Fichier, puis vérifiez si le premier caractère est U + FEFF. Vous pouvez le faire en ouvrant un FRStream à base de charret normal, puis utilisez WBuffer_Convert pour le traiter comme une série d'unités de code dans un autre encodage. Vs2010 n'a pas encore d'excellent support pour CHAR32_T, donc les utilisations suivantes UTF-16 dans WCHAR_T. P>

std::wifstream fin(filename);
fin.imbue(std::locale(fin.getloc(), new std::codecvt_utf8_utf16<wchar_t, 0x10FFFF, std::consume_header));


0 commentaires

0
votes

Avec une solution non si propre, j'ai résolu en supprimant les caractères non d'impression: xxx

... xxx


0 commentaires