Lecture de fichier ASCII / UNICODE. DEBUTANT
Bonjour à tous,
C'est la première fois que je viens poster sur ce forum. Je débute en c++, même si j'ai longtemps 'bricoler' en C. Je bloque aujourd'hui sur un problème extrêmement bête que je ne comprend pas.
Voici mon code :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string line;
fstream text("monfichier.txt");
while (getline(text,line))
{
cout << line << endl;
}
return 0;
} |
Il n'y a, pour la plupart des fichiers que je traite, aucun problème, par contre j'ai pu identifier, sur des fichiers registre (*.reg) un problème lors de la sortie de ma chaine.
En effet, celle ci contient des espaces entre chaque caractère, c'est très pénible à traiter.
Quand j'affiche la variable çà écrit par exemple ce genre de chose :
[ H K E Y _ C U R R E N T _ C O N F I G \ \ S y s t e m \ C u r r e n t C o n t r o l S e t \ C o n t r o l \ V I D E O ]
alors que mon fichier d'origine contient bien :
[HKEY_CURRENT_CONFIG\\System\CurrentControlSet\Control\VIDEO]
Et du coup impossible de , par exemple, réinjecter les chaine obtenu dans un nouveau fichier.
J'ai testé avec des .reg fabriqué manuellement il n'y a aucun probléme.
Les fichiers qui présente des problèmes sont fabriqué à partir de la commande regedit /e.
Ce que je ne comprend absolument pas c'est pourquoi cette différence de résultat alors que les fichiers sont traités de la même manière?
J'ai clairement loupé un truc essentiel mais quoi?
Si quelqu'un veux bien m'éclairer?
Merci d'avance
Convertir un fichier de UTF-16 vers UTF-8 avec la STL, en passant par UTF-32.
Au cas où mon code soit utile à quelqu'un, voici un programme qui lit un fichier encodé en UTF-16 et le convertit en UTF-8 :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include <codecvt>
#include <fstream>
#include <iostream>
#include <locale>
int main(int argc, char** argv)
{
try {
if(argc < 2) {
throw std::runtime_error("Pas assez d'arguments. Il en faut deux :"
" l'adresse d'un fichier en entree encode en UTF-16"
" et l'adresse d'un fichier en sortie qui sera encode en UTF-8.");
}
const char* const cheminFichierEntreeUTF16 = argv[1];
const char* const cheminFichierSortieUTF8 = argv[2];
std::basic_ifstream<char32_t> fic_entree_utf16(cheminFichierEntreeUTF16, std::ios::binary);
if(!fic_entree_utf16)
throw std::runtime_error("Impossible d'ouvrir le fichier en entree.");
fic_entree_utf16.imbue(std::locale(
fic_entree_utf16.getloc(),
new std::codecvt_utf16<char32_t, 0x10ffff, std::consume_header>
));
std::basic_ofstream<char32_t> fic_sortie_utf8(cheminFichierSortieUTF8, std::ios::binary);
if(!fic_sortie_utf8)
throw std::runtime_error("Probleme avec le fichier en sortie.");
fic_sortie_utf8.imbue(std::locale(
fic_sortie_utf8.getloc(),
new std::codecvt_utf8<char32_t, 0x10ffff, std::generate_header>
));
char32_t carac_utf32;
while(fic_entree_utf16.good())
{
fic_entree_utf16.get(carac_utf32);
if(fic_entree_utf16.fail() == false)
{
fic_sortie_utf8 << carac_utf32;
if(fic_sortie_utf8.fail())
throw std::runtime_error("Probleme lors de l'ecriture du fichier en sortie.");
}
}
} catch(const std::exception& e) {
std::cerr << e.what();
return 1;
} catch(...) {
std::cerr << "Erreur inconnue.";
return 2;
}
return 0;
} |
Remarques :
- S'il n'y a pas de caractère BOM dans le fichier en entrée, il faut remplacer std::consume_header par (std::codecvt_mode)0 (qui est déjà l'argument de template par défaut) ou std::little_endian.
- Si on ne veut pas de caractere BOM dans le fichier en sortie, il faut remplacer std::generate_header par (std::codecvt_mode)0.