web-dev-qa-db-fra.com

Comment écrire un std :: string dans un fichier texte UTF-8

Je veux juste écrire quelques lignes simples dans un fichier texte en C++, mais je veux qu'elles soient encodées en UTF-8. Quel est le moyen le plus simple et le plus simple de le faire?

55
poiloi

La seule manière dont UTF-8 affecte std::string est que size(), length() et tous les index sont mesurés en octets, pas en caractères.

Et, comme le fait remarquer sbi, incrémenter l'itérateur fourni par std::string avancera par octet et non par caractère, de sorte qu'il puisse pointer au milieu d'un point de code UTF-8 multi-octets. Il n'y a pas d'itérateur compatible UTF-8 fourni dans la bibliothèque standard, mais quelques-uns sont disponibles sur le Net.

Si vous vous en souvenez, vous pouvez mettre UTF-8 dans std::string, l'écrire dans un fichier, etc., de la manière habituelle (j'entends par là la façon dont vous utiliseriez un std::string sans UTF-8 à l'intérieur).

Vous souhaiterez peut-être démarrer votre fichier avec une marque d'ordre d'octets afin que les autres programmes sachent qu'il s'agit du format UTF-8.

53
Ben Voigt

Il existe une jolie petite bibliothèque pour travailler avec utf8 à partir de c ++: utfcpp

24
denys

libiconv est une excellente bibliothèque pour tous nos besoins d’encodage et de décodage.

Si vous utilisez Windows, vous pouvez utiliser WideCharToMultiByte et spécifier que vous voulez UTF8.

10
Brian R. Bondy

Quel est le moyen le plus simple et le plus simple de le faire?

Le traitement le plus intuitif et donc le plus simple d’utf8 en C++ est bien sûr d’utiliser un remplaçant drop-in pour std::string . Étant donné qu’Internet n’en manque toujours pas, j’ai mis en œuvre la fonctionnalité moi-même:

tinyutf8 (EDIT: maintenant Github).

Cette bibliothèque fournit un préplacement d'insertion très léger pour std::string (ou std::u32string si vous préférez, car vous effectuez une itération sur points de code plutôt que sur char s). Ity est implémenté avec succès à mi-chemin entre accès rapide et faible consommation de mémoire, tout en étant très robuste. Cette robustesse aux séquences UTF8 "non valides" le rend (presque complètement) compatible avec ANSI (0-255).

J'espère que cela t'aides!

9
Jakob Riedle

Si vous entendez "simple" par ASCII, vous n'avez pas besoin d'encoder, car les caractères avec une valeur ASCII de 127 ou moins sont identiques en UTF-8. 

7
Tony the Pony
std::wstring text = L"Привет";
QString qstr = QString::fromStdWString(text);
QByteArray byteArray(qstr.toUtf8());    
std::string str_std( byteArray.constData(), byteArray.length());
5
Serov Danil

Ma préférence est de convertir vers et à partir d'un std :: u32string et de travailler avec des points de code en interne, puis de convertir en utf8 lors de l'écriture dans un fichier à l'aide de ceux-ci convertir les itérateurs que j'ai mis sur github.

#include <utf/utf.h>

int main()
{
    using namespace utf;

    u32string u32_text = U"ɦΈ˪˪ʘ";
    // do stuff with string
    // convert to utf8 string
    utf32_to_utf8_iterator<u32string::iterator> pos(u32_text.begin());
    utf32_to_utf8_iterator<u32string::iterator> end(u32_text.end());

    u8string u8_text(pos, end);

    // write out utf8 to file.
    // ...
}
0
rmawatson