Remplacement de chaines de caractères par une autre [ /!\ ANSI ]°

Signaler
Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
-
Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
-
Bonjour,

Nouveau petit souci... oui encore...

J'aimerai trouver et remplacer toutes les chaines de caractères ANSI par une autre chaine de caractères ANSI.
Exemple, je voudrai que mon code/fonction cherche îOLÃAl\ et les remplace par babarhum.

J'ai testé différentes soluces dont :
Citation:
montexte.Replace("îOLÃAl", "babarhum");

ou
string text = System.IO.File.ReadAllText(OFD1.FileName);
            String resultat = text.Replace("Ã", "e");


Sans succés, car .Replace(X,Y) ne reconnait pas le ANSI mais je ne sais quel autre jeu de caractère.

Merci du coup de main.

10 réponses

Messages postés
72
Date d'inscription
vendredi 16 mai 2003
Statut
Membre
Dernière intervention
12 août 2009
2
Le string est en UTF-16. Opérer une telle substitution directement au niveau des chaînes de caractère représentant les données binaires est hasardeux. Mais bon je ne vois pas pourquoi cela ne marcherait pas. Au passage, je te signale que tu n'as pas correctement échappé le backslash.

Je te conseillerais de créer d'abord une classe capable de localiser et de remplacer une suite de bytes à l'intérieur d'une autre suite de bytes. A moins que cela n'existe déjà dans le Framework, mais je ne le trouve pas.

Alors tu pourras transformer ta chaîne ANSI (Windows-1252) en bytes et procéder à l'opération. Sachant que c'est une solution imparfaite, puisque nombre de caractères de la table ANSI ne peuvent pas être tappés au clavier et que cela ne vaudra donc jamais la substitution "hexadécimale".

Mathieu.
Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
1
Merci encore de ta réponse. Si je comprends bien le mieux est donc une substitution hexa.

Pour être franc, à la base, je cherchai un moyen de remplacer et modifier une chaine hexa par une autre.
Ne trouvant pas de moyen simple (mon niveau en c# étant bien faible et mon temps libre très limité, j'essaie de trouver des astuces), j'ai penser changer ce mode de recherche/remplacement par un plus simple permettant simplement ce changement. Je suis donc passé de l'hexa au jeu de caractère ANSI.

Mais, je vois que je me retrouve donc dans mon impasse originale. :/
Messages postés
72
Date d'inscription
vendredi 16 mai 2003
Statut
Membre
Dernière intervention
12 août 2009
2
Pour être honnête, un éditeur hexadécimal semble simple à première vue mais ce n'est pas une bonne idée pour un débutant. De surcroît, le Framework .NET n'est pas nécessairement un outil très adapté à cela.

La routine pour localiser et remplacer la séquence de byte va être un petit peu indigeste, surtout si tu ne veux pas charger tout le fichier en mémoire.

Mathieu.
Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
1
Ah... et que me conseillerais-tu comme langage pour le remplacement/échange/remplacement de chaine hexa? stp.
Messages postés
72
Date d'inscription
vendredi 16 mai 2003
Statut
Membre
Dernière intervention
12 août 2009
2
J'ai bricolé en vitesse ceci :

static void Main ()
    {
        byte[] Fichier = new byte[] { 55, 255, 0, 1, 165 };
        byte[] OSequence = new byte[] { 165 };
        byte[] RSequence = new byte[] { 187 };
        Replace (Fichier, OSequence, RSequence);
        foreach (byte AByte in Fichier)
            Console.WriteLine (AByte);
        Console.ReadLine ();
    }
    static void Replace (byte[] ByteArray, byte[] OriginalSequence, byte[] ReplacementSequence)
    {
        if (OriginalSequence.Length > ByteArray.Length)
            throw new ArgumentException ();
        if (OriginalSequence.Length != ReplacementSequence.Length)
            throw new ArgumentException ();

        for (int i = 0; i < ByteArray.Length - OriginalSequence.Length + 1; i++)
        {
            for (int j = 0; j < OriginalSequence.Length; j++)
            {
                if (ByteArray[i + j] != OriginalSequence[j])
                    break;
                if (j == OriginalSequence.Length - 1)
                {
                    for (int k = 0; k < OriginalSequence.Length; k++)
                    {
                        ByteArray[i] = ReplacementSequence[k];
                        i++;
                    }
                    break;
                }
            }
        }
    }
Messages postés
72
Date d'inscription
vendredi 16 mai 2003
Statut
Membre
Dernière intervention
12 août 2009
2
Tu peux évidemment chercher et remplacer une séquence de plusieurs bytes :

byte[] OSequence = new byte[] { 1, 165 };
byte[] RSequence = new byte[] { 2, 187 };

Comme tu vois, on part vite dans des boucles de boucles de boucles ...

Ce serait aussi indigeste dans un autre langage. Ce n'est pas le C# que je mets en cause, mais le fait que la bibliothèque de classes du Framework .NET ne contienne pas d'outil pour faire cela ... enfin je crois. En tout cas je ne l'ai jamais trouvé !

Si tu ne veux pas charger tout le fichier en mémoire, tu vas devoir adapter le code pour passer par un BinaryReader, un fichier temporaire et un BinaryWriter.

Mathieu.
Messages postés
72
Date d'inscription
vendredi 16 mai 2003
Statut
Membre
Dernière intervention
12 août 2009
2
Petite correction :

for (int k = 0; k < OriginalSequence.Length; k++)
                    {
                        ByteArray[i] = ReplacementSequence[k];
                        i++;
                    }
                    i--;
                    break;


Mathieu.
Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
1
Merci de prendre du temps pour moi, c'est très sympa.

Ton code intégré dans le mien, extrait :
private void button1_Click(object sender, EventArgs e)
        {
            OFD1.FileName = "";
            OFD1.Title = "Fichier à modifier";
            OFD1.ShowDialog();
            if (OFD1.FileName != "")
            {
                GlobalVariables.FilePath = OFD1.FileName;
                button2.Enabled = true;
                
            }
        }


private void button2_Click(object sender, EventArgs e)
        {
            byte[] Fichier = Encoding.Default.GetBytes(OFD1.FileName);
            byte[] OSequence = new byte[] { 17 };
            byte[] RSequence = new byte[] { 14 };
            replace(Fichier, OSequence, RSequence);

            foreach (byte AByte in Fichier)

            Console.WriteLine(AByte);

            Console.ReadLine();

        static void replace(byte[] ByteArray, byte[] OriginalSequence, byte[] replacementSequence)
        {

            if (OriginalSequence.Length > ByteArray.Length)

                throw new ArgumentException();

            if (OriginalSequence.Length != replacementSequence.Length)

                throw new ArgumentException();



            for (int i = 0; i < ByteArray.Length - OriginalSequence.Length + 1; i++)
            {

                for (int j = 0; j < OriginalSequence.Length; j++)
                {

                    if (ByteArray[i + j] != OriginalSequence[j])

                        break;

                    if (j == OriginalSequence.Length - 1)
                    {

                        for (int k = 0; k < OriginalSequence.Length; k++)
                        {

                            ByteArray[i] = replacementSequence[k];

                            i++;

                        }

                        i--;

                        break;

                    }

                }

            }

        }


Mon intégration ne semble pas être bonne, car ça ne modifie rien de mon fichier ouvert via le bouton 1.
Messages postés
72
Date d'inscription
vendredi 16 mai 2003
Statut
Membre
Dernière intervention
12 août 2009
2
J'ai ajouté une source ici, avec des explications :
http://www.csharpfr.com/codes/REMPLACER-SEQUENCE-BYTE_50417.aspx

Encoding.Default.GetBytes(OFD1.FileName)


Avec ça, tu ne vas pas récupérer les bytes du fichier dont le nom est dans OFD1.FileName, mais les bytes des caractères qui composent la chaîne OFD1.FileName selon la page ANSI actuelle du système d'exploitation.

Pour les bytes du fichier tu devrais faire :
FileStream StreamFichier = new FileStream(OFD1.FileName, FileMode.Open, FileAccess.Read);
byte[] Fichier = new byte[StreamFichier.Length];
StreamFichier.Read(Fichier, 0, System.Convert.ToInt32(StreamFichier.Length));


Et de toute façon, cela ne modifiera rien dans ton fichier, mais seulement dans byte[] Fichier, qui est une copie de ton fichier dans la mémoire de l'application. Pour modifier le fichier, tu dois encore réécrire les données modifiées.

Mathieu.
Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
1
Très bien merci encore, je me replonge dedans quand j'ai un peu de temps, j'espère ce soir ou ce weekend.