IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Caractères invisibles à Windows


Sujet :

C#

  1. #1
    Membre régulier
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Janvier 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Janvier 2010
    Messages : 119
    Points : 77
    Points
    77
    Par défaut Caractères invisibles à Windows
    Salut à tous,
    j'ai un fichier .txt avec une ligne qui possède des caractères invisibles à Windows. Quand j'importe ce fichier sous UNIX, ses caractères apparaissent clairement.

    La ligne sous Windows :
    021000012509140420121600000000000xxxxxxxxxxxxxxxxxxxxxxxx00000
    la ligne sous UNIX :
    \357\273\277021000012509140420121600000000000xxxxxxxxxxxxxxxxxxxxxxxx00000
    Mon souci est de pouvoir vérifier la présence de ses caractères et ramener un message erreur avec la ligne concernée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    //Effectue un test sur le fichier afin de contrôler les caractères invisibles
                    bool retour = true;
                    int longueurLigne = 128; // Les caractères maximum sur une ligne doivent etre de 128.
                    StreamReader sr = new StreamReader(FILEDIALOG.FileName, Encoding.UTF8); //recuperation du fichier à controler
     
                    string s = string.Empty;
                    while ((s = sr.ReadLine()) != null)
                    {
                        if (s.Length > longueurLigne)
                        {
                            retour = false;
                            string[] lines_caractere = { "Présence de caractères invisibles sur la ligne : " + " " + s };
                            //remplir le fichier erreur.txt avec retour à la ligne
                            System.IO.File.WriteAllLines(Application.StartupPath + "\\erreur.txt", lines_caractere);
                            TXT.Text = "";
                        }
                    }
                    string text = Convert.ToString(retour);
    Ce code ne détecte pas la présence des caractères invisibles en début de lignes et Je sollicite votre aide.

  2. #2
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 191
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 191
    Points : 28 070
    Points
    28 070
    Par défaut
    Le caractère représenté par la notation \357\273\277 dans ton exemple est très certainement un caractère invisible appelé "espace insécable sans chasse" ("zero-width no-break space" en anglais), codé sur 4 octets. Lorsque ce caractère est situé en toute première place d'un fichier, ce n'est pas un caractère mais ce que l'on appelle le BOM (Byte Order Mark) qui est là pour indiqué que ton fichier est en enregistré au format unicode et indique quel type d'unicode.

    La solution est soit d'ouvrir ton fichier en spécifiant que c'est de l'unicode avec BOM, si ton logiciel le permet, soit de convertir ton fichier en unicode sans BOM. Dans ce cas, ce caractère n'y serait pas, et le logiciel devra savoir quel unicode il devra utiliser (ce qui généralement ne pose aucun problème).
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Effectivement "\357\273\277" correspond à la notation octale du BOM UTF-8 (EF BB BF en hexa)

    Normalement les éditeurs modernes savent traiter correctement ce code qui indique que le fichier est encodé en UTF-8 ; en aucun cas ils ne doivent être affichés. Je ne sais pas quel éditeur tu utilises sous UNIX, mais il doit dater un peu

    Ce code ne détecte pas la présence des caractères invisibles en début de lignes
    Au contraire, il les détecte et les ignore, ce qui est le comportement correct... Pourquoi cherches-tu à contrôler la présence de ces caractères ?

  4. #4
    Membre régulier
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Janvier 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Janvier 2010
    Messages : 119
    Points : 77
    Points
    77
    Par défaut
    Merci à sevyc64 et tomlev pour vos réponses.

    Pourquoi cherches-tu à contrôler la présence de ces caractères ?
    Le nombre d'enregistrements sur une ligne doit être de 128 caractères. Alors je veux pouvoir vérifier la présence de ces "espaces insécables sans chasse" afin de détecter si le nombre d'enregistrements sur une ligne n'excède pas les 128 caractères. Le traitement de ce fichier se fait sur un applicatif installé sur le système UNIX. Les caractères sont invisibles et ignorés sous WINDOWS mais visibles sous UNIX et du coup cela crée un problème. Je ne sais pas si mon explication est claire.

    Comment puis-je détecter la présence de ces caractères en début de fichier ?

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    OK, donc il faut que tu re-encodes le fichier dans un format que ton applicatif UNIX comprend. Est-ce qu'il comprend l'UTF-8 sans BOM au moins?

    Si oui tu peux faire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    var utf8WithoutBOM = new UTF8Encoding(false);
    TranscodeFile(inputFile, Encoding.UTF8, outputFile, utf8WithoutBOM);
     
    ...
     
    private void TranscodeFile(string inputFile, Encoding inputEncoding, string outputFile, Encoding outputEncoding)
    {
         using (var reader = new StreamReader(inputFile, inputEncoding))
         using (var writer = new StreamWriter(outputFile, false, outputEncoding))
         {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                writer.WriteLine(line);
            }
         }
    }
    Si ça marche pas bien (par exemple les caractères accentués qui passent pas), essaie avec un autre encodage comme Encoding.Default ou Encoding.GetEncoding("iso-8859-1") à la place de utf8WithoutBOM

  6. #6
    Membre régulier
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Janvier 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Janvier 2010
    Messages : 119
    Points : 77
    Points
    77
    Par défaut
    OK, donc il faut que tu re-encodes le fichier dans un format que ton applicatif UNIX comprend. Est-ce qu'il comprend l'UTF-8 sans BOM au moins?
    tomlev, re-encodé le fichier ne résoudra pas le problème. Je serai encore obligé de traiter un fichier en sortie avec le nouveau code. Or je veux simplement vérifier la présences des caractères "espaces insécables sans chasse" et afficher un message d'erreur à l'utilisateur afin qu'il transfert le fichier au service compétent pour la correction sur UNIX.

    Je fais ce code qui me renvoi pour l'instant l'encodage du fichier, mais je n'arrive toujours pas à détecter la présence des caractères dans le fichier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    utf8 = new UTF8Encoding(false);
                    string fileName = FILEDIALOGBIAO.FileName;
                    string[] lignes = File.ReadAllLines(fileName);
                    int lignesfichier = lignes.Length;
     
                    Encoding enc = null;
                    FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                    if (file.CanSeek)
                    {
                        byte[] bom = new byte[4]; // Obtenez la marque d'ordre d'octet, s'il en existe un
                        file.Read(bom, 0, 4);
                        if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) // utf-8
                        {
                            enc = Encoding.UTF8;
                        }
                        else if ((bom[0] == 0xff && bom[1] == 0xfe) || // ucs-2le, ucs-4le, and ucs-16le
                            (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff)) // ucs-4
                        {
                            enc = Encoding.Unicode;
                        }
                        else if (bom[0] == 0xfe && bom[1] == 0xff) // utf-16 and ucs-2
                        {
                            enc = Encoding.BigEndianUnicode;
                        }
                        else // ANSI, Default
                        {
                            enc = Encoding.Default;
                        }
                        // Maintenant repositionner le fichier curseur au début du fichier
                        file.Seek(0, SeekOrigin.Begin);
                    }
                    else
                    {
                        enc = Encoding.Default;
     
                    }
                    MessageBox.Show(Convert.ToString(enc));

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par degio1er Voir le message
    Or je veux simplement vérifier la présences des caractères "espaces insécables sans chasse" et afficher un message d'erreur à l'utilisateur afin qu'il transfert le fichier au service compétent pour la correction sur UNIX.
    Oublie cette histoire d'espace insécable sans chasse, c'est pas ça de toutes façons. Le caractère insécable sans chasse, c'est U+FEFF, qui est également utilisé pour les BOMs UTF-16 et UTF-32, mais pas UTF-8. Et de toutes façons c'est pas ça que tu as dans ton fichier...

    Pour détecter s'il y a un BOM UTF-8, tu peux faire une fonction comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    bool HasUTF8BOM(string path)
    {
        using (var stream = File.OpenRead(path))
        {
            var buffer = new byte[3];
            stream.Read(buffer, 0, buffer.Length);
            var bom = Encoding.UTF8.GetPreamble();
            return buffer.SequenceEqual(bom);
        }
    }

  8. #8
    Membre régulier
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Janvier 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Janvier 2010
    Messages : 119
    Points : 77
    Points
    77
    Par défaut
    Après plusieurs recherches voilà un peu ce que j'ai pu faire
    En effet, j'ai crée une table codeascii avec les différentes informations ascii trouvées sur ce site http://www.theasciicode.com.ar/
    ensuite, je lis le fichier caractère par caractère en faisant des requêtes de vérification dans ma table codeascii. si le code ascii d'un caractère n'est pas présent dans la table alors je génère un message d'erreur dans mon fichier. Ci-dessous mon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    string fileName = FILEDIALOGBIAO.FileName;
                    string[] lignes = File.ReadAllLines(fileName);
                    int lignesfichier = lignes.Length;
                    FileStream   fs;
                    BinaryReader br;
     
                    // Contrôle des caractères invisibles à Windows
     
                    //Lecture du fichier à partir de la position 0 
                    fs = File.Open(fileName, FileMode.Open);
                    fs.Seek(0, SeekOrigin.Begin);
                    br = new BinaryReader(fs) ;
                   // while (fs.Position < fs.Length)
                    for (int ii = 1; ii < lignesfichier; ii++)
                    {
                        //MessageBox.Show(Convert.ToString( br.ReadByte())) ; 
                        string codeascii = Convert.ToString(br.ReadByte());
                        string requete_codeascii = "select Code as cptcode from codeascii where Code = '" + codeascii + "' ";
                        OleDbDataReader lire_requete_codeascii = cls.ouvrirRequète(requete_codeascii, maconnexion);
                        while (lire_requete_codeascii.Read())
                        {
                            int code_ascii = Convert.ToInt16(lire_requete_codeascii["cptcode"]);
                            if (code_ascii == 0)
                            {
                                string[] lines_caractere = { "Caractères invisibles présent dans le fichier." };
                                //remplir le fichier erreur.txt avec retour à la ligne
                                System.IO.File.WriteAllLines(Application.StartupPath + "\\fichiererreur.txt", lines_caractere);
     
                            }
                        }
                    }

    J'ai fais le teste avec deux fichiers possédant les caractères mais le troisième fichier possédant les caractères ne me génère pas d'erreur, chose que je ne comprends pas d'ailleurs.

  9. #9
    Membre du Club
    Inscrit en
    Février 2013
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 34
    Points : 43
    Points
    43
    Par défaut
    En gros si je comprend bien ton soucis tu veux qu ton fichier soit " bien formé " et que chaque ligne possede 128 caractèrs.
    Le mieux a faire ça reste de vérifier qu'il est encodé en ASCII. C'est facile : établis la liste de tous les octets ASCII autorisés ( normalement ça voudra dire octet > 31 et <128).
    N'utilise surtout pas de convert.tostring ou sinon tes caractères non autorisés ne vont pas apparaitre..

    http://www.juniper.net/techpubs/en_U...ded-ascii.html

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par degio1er Voir le message
    En effet, j'ai crée une table codeascii avec les différentes informations ascii trouvées sur ce site http://www.theasciicode.com.ar/
    ensuite, je lis le fichier caractère par caractère en faisant des requêtes de vérification dans ma table codeascii.
    Tu fais une requête SQL pour chaque caractère de ton fichier ?

    Ca va être marrant le jour où tu vas devoir traiter un fichier de quelques centaines de Mo....

  11. #11
    Membre régulier
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Janvier 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Janvier 2010
    Messages : 119
    Points : 77
    Points
    77
    Par défaut
    Bonjour à tous,
    la solution que j'ai adoptée pour l'instant est celle des caractères de la table ASCII. En effet, j'ai crée dans ma base une table contenant les caractères. Et je fais le contrôle de chaque en vérifiant bien sur si ce caractères existe dans ma table, sinon j'affiche un message à l’utilisation "Caractère invisible à WINDOWS, merci de contacter le service compétent pour le nécessaire à faire ".
    En fait la correction de ces caractères est faite sur le système UNIX (SALORIS). Si quelqu'un à quelque chose de plus performant! je suis vraiment disponible.

Discussions similaires

  1. Suppression de caractère invisible
    Par lodan dans le forum Langage
    Réponses: 10
    Dernier message: 02/10/2008, 17h55
  2. [RegEx] Supprimer caractères invisibles au sein d'une chaîne
    Par webrider dans le forum Langage
    Réponses: 9
    Dernier message: 19/04/2007, 12h07
  3. Augmenter le nombre max de caractères sous windows..
    Par saebakun dans le forum Autres Logiciels
    Réponses: 5
    Dernier message: 17/08/2006, 16h25
  4. Erreur cannot focus a disabled or invisible window
    Par Andry dans le forum Composants VCL
    Réponses: 3
    Dernier message: 17/12/2003, 08h33
  5. Polices de caractères sous Windows
    Par goto dans le forum API, COM et SDKs
    Réponses: 24
    Dernier message: 04/11/2003, 16h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo