Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les forums > Programmation > Langage C++ > [Exercices] Venez vous entraîner ! > Lecture du sujet

[Exercices] Venez vous entraîner !

Un nouvel exercice chaque mois

Vous devez être inscrit pour pouvoir poster des messages

Page : Précédente  1  2  3  ...  13  14  15  16  17  18  19  ...  26  27  28  29  Suivante
Auteur Message
1 visiteur sur ce sujet (1 anonyme)
Page : Précédente  1  2  3  ...  13  14  15  16  17  18  19  ...  26  27  28  29  Suivante
Hors ligne BoudBoulMan # Posté le 01/07/2008 à 20:03:19
Saucisse transgénique
Avatar
Groupe : Membres
Reprise du dernier message de la page précédente :
Donc, en fait dès que t'as au moins 2 sauts à la ligne successifs, il y a un changement de paragraphe.
Hors ligne gogeta1 # Posté le 01/07/2008 à 20:06:08
Naruto vs Sasuke
Avatar
Groupe : Membres
Ah excuse moi, j'avais mal lu ^^

Pong (Concours C++) :
100% : ||||||||||
 
Hors ligne Kurlze # Posté le 01/07/2008 à 20:17:59
L.O.S.T
Avatar
Groupe : Membres
Citation : BoudBoulMan
Donc, en fait dès que t'as au moins 2 sauts à la ligne successifs, il y a un changement de paragraphe.


Pourquoi 2 ? Théoriquement un seul suffit.

You cannot change your fate. No man can.
 
Hors ligne gymnopaul # Posté le 01/07/2008 à 20:52:13
I could go supersonic !
Avatar
Groupe : Membres
Ben dans ce cas-là un paragraphe devrait tenir sur une seule ligne !

Projet en cours : 2D-3D-Games -> Tutoriels vidéo sur la création de jeux vidéos
Mes connaissances :
Langages : C - C++ (mon préféré ^^ ) - HTML - PHP - SQL
3D : Blender

 
Hors ligne Bachir ElMagnifico # Posté le 01/07/2008 à 20:54:51
http://info-crea.tuxfamily.org
Avatar
Groupe : Membres
tu peux continuer dans la meme ligne apres un point ;)

Image utilisateur
cherche des partenaires - page de contact.
mon tuto sur OgreNewt: partie 1, partie 2, partie 3, partie 4
 
Hors ligne BoudBoulMan # Posté le 01/07/2008 à 20:59:59
Saucisse transgénique
Avatar
Groupe : Membres
Citation : Kurlze
Citation : BoudBoulMan
Donc, en fait dès que t'as au moins 2 sauts à la ligne successifs, il y a un changement de paragraphe.


Pourquoi 2 ? Théoriquement un seul suffit.

Non, tu peux avoir des sauts à la ligne dans un paragraphe.
Hors ligne Chlab_lak # Posté le 01/07/2008 à 21:03:32
Tendou : Royaume de dieu
Avatar
Groupe : Membres
Hors ligne Nanoc # Posté le 01/07/2008 à 21:11:52
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
Non. Ce n'est pas ce que j'ai écrit.

Citation

\n
blabla
\n


Ceci est un paragraphe. Je n'ai pas précisé combien de \n il devait y avoir avant et après. J'ai dit qu'il devait y en avoir (au moins) un avant et (au moins) un après un bloc de texte.
 
Hors ligne Chlab_lak # Posté le 01/07/2008 à 21:19:37
Tendou : Royaume de dieu
Avatar
Groupe : Membres
dans ce cas là il y a un problème avec le paragraphe qui se trouve au début.

Le mieux est de compter le nombre de fois qu'il y a deux retour à la ligne à la suite (\n\n) suivient de plusieurs mots, puis d'incrémenter pour ne pas oublier le dernier OU premier. Cette façon de faire m'a l'air bien, après j'ai peut-etre oublié qqch
 
Hors ligne Bachir ElMagnifico # Posté le 01/07/2008 à 21:22:03
http://info-crea.tuxfamily.org
Avatar
Groupe : Membres
tu n'as toujours pas vu les participations?

Image utilisateur
cherche des partenaires - page de contact.
mon tuto sur OgreNewt: partie 1, partie 2, partie 3, partie 4
 
Hors ligne BoudBoulMan # Posté le 01/07/2008 à 21:25:19
Saucisse transgénique
Avatar
Groupe : Membres
Citation : Nanoc
Non. Ce n'est pas ce que j'ai écrit.

Citation

\n
blabla
\n


Ceci est un paragraphe. Je n'ai pas précisé combien de \n il devait y avoir avant et après. J'ai dit qu'il devait y en avoir (au moins) un avant et (au moins) un après un bloc de texte.

Ok, donc une ligne est considérée comme un paragraphe ici?
Si on le définit clairement comme ça pour l'exo, je suis d'accord.
Hors ligne Nanoc # Posté le 01/07/2008 à 21:27:33
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
Citation : Chlab_lak
dans ce cas là il y a un problème avec le paragraphe qui se trouve au début.

Le mieux est de compter le nombre de fois qu'il y a deux retour à la ligne à la suite (\n\n) suivient de plusieurs mots, puis d'incrémenter pour ne pas oublier le dernier OU premier. Cette façon de faire m'a l'air bien, après j'ai peut-etre oublié qqch


C'est pas un problème, il faut juste y penser. Un texte est composé au minimum d'un paragraphe. Avec ta méthode, tu comptes les sauts de paragraphes. Il peut très bien y avoir 5 retours à la ligne entre deux paragraphes. C'est une question d'esthétique. De plus avec ta méthode, il faut aussi penser au premier paragraphe, puisque il peut potentiellement ne jamais avoir de \n dans un texte.
 
Hors ligne Chlab_lak # Posté le 01/07/2008 à 21:39:13
Tendou : Royaume de dieu
Avatar
Groupe : Membres
Je ne vois toujours pas de problème dans ma méthode, peut-être qu'on se comprend mal.
Voilà à quoi je pense:

Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
size_t 
compter_paragraphe(std::istream &fichier)
{
   size_t nombre_paragraphe = 0;

   /*
   ici, on compte le nombre de fois qu'il y a 
   deux (ou plus)  sauts de ligne à la suite
   suivient de un (ou plusieurs) mots.
   */

   return nombre_paragraphe + 1;
}
 
Hors ligne Nanoc # Posté le 02/07/2008 à 08:43:50
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
Citation : http://fr.wikipedia.org/wiki/Paragraphe
En bonne typographie, on appelle paragraphe un segment de texte suivi (dit aussi texte linéaire) compris entre deux alinéas.


Je dis pas que ta méthode ne permet pas le calcul, mais ce n'est pas la définition.
 
Hors ligne BoudBoulMan # Posté le 02/07/2008 à 10:36:25
Saucisse transgénique
Avatar
Groupe : Membres
Faudrait peut-être préciser la définition dans l'énoncé, ça évitera les mauvaises interprétations.
Hors ligne gymnopaul # Posté le 02/07/2008 à 11:08:08
I could go supersonic !
Avatar
Groupe : Membres
Argh en fait c'est pas si facile que ça en a l'air :-° . Le problème c'est que je sais pas trop utiliser les méthodes des chaînes et des fichiers...

Projet en cours : 2D-3D-Games -> Tutoriels vidéo sur la création de jeux vidéos
Mes connaissances :
Langages : C - C++ (mon préféré ^^ ) - HTML - PHP - SQL
3D : Blender

 
Hors ligne Buldozer[FR] # Posté le 02/07/2008 à 11:20:34
Avatar
Groupe : Membres
Le 28, j'ai envoyé ma réponse à l'exercice de compression, mais il n'a toujours pas été regardé....

Image utilisateur
Image utilisateur
 
Hors ligne Nanoc # Posté le 02/07/2008 à 11:23:22
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
C'est normal, j'attends la fin du mois pour tout regarder. Et après, je fais ça quand j'ai le temps. Ce qui sera le cas vendredi normalement.
 
Hors ligne Buldozer[FR] # Posté le 02/07/2008 à 11:32:15
Avatar
Groupe : Membres
ok merci

Image utilisateur
Image utilisateur
 
Hors ligne Eclyps # Posté le 02/07/2008 à 13:28:22
Kenny Noël , Yep! Yep! Yep!
Avatar
Groupe : Membres
J'ai fini !
(Pour une fois que j'avais du temps libre, j'ai pu faire l'exercice)
Manque plus qu'as faire un jolie code et a bien présenter la console :p .

QScintilla Ma Playlist Image utilisateur
Image utilisateur No Life Test
Image utilisateur Geek Test
Image utilisateur Nerd Test
 
Hors ligne moa3788 # Posté le 02/07/2008 à 21:20:28
Avatar
Groupe : Membres
Bonjour a tous.

Etant un peu rouillé en C++ et voulant m'y remettre je viens de découvrir vos petits exercices pile ce qu'il me fallait (simples mais efficaces, puis j'ai pas le temps de mettre au gros concours (boulot quand tu nous tiens)).

Donc je pense me joindre à vous pour l'exercice de juillet (quasiment fini d'ailleurs).

Néanmoins quelques précisions sur les résultats attendus: quels qont les caractères a comptabiliser (les \n \t ...) sont-ils des caractères. Quels sont les séparateurs de mots à prendre en compte( , ; . ...)

Je demande car impossible d'obtenir le même résultat que word ou open office (qui eux même n'ont pas le même résultat....)

On est juste d'accord sur le nombre de paragraphes, pour le reste j'ai un résultat entre les 2...

Merci pour ces quelques pécisions

EDIT: Finalement j'ai trouvé les paramètre utilisés par word, j'arrive au même résultat: dont-on prendre ces paramètres ou ceux de OO (ou autre...)
Édité le 02/07/2008 à 21:40:23 par moa3788
Hors ligne BoudBoulMan # Posté le 02/07/2008 à 22:06:17
Saucisse transgénique
Avatar
Groupe : Membres
Citation : moa3788
Néanmoins quelques précisions sur les résultats attendus: quels qont les caractères a comptabiliser (les \n \t ...) sont-ils des caractères. Quels sont les séparateurs de mots à prendre en compte( , ; . ...)

\n et \t sont bien des caractères à comptabiliser pour le nombre total de caractères mais pas dans celui de caractères sans espaces
vu que les espaces c'est l'espace, \n, \t, ... ou sinon cela n'aurait aucun rapport de différencier les deux.

Pour les séparateurs de mot, j'en sais rien :euh:
Édité le 02/07/2008 à 22:06:48 par BoudBoulMan
Hors ligne M41d3n-dc # Posté le 02/07/2008 à 22:34:05
Mode sudo activé !!
Avatar
Groupe : Membres
on peut essayer de le faire avec Qt ou seulement avec la console ?
merci

Image utilisateur
Image utilisateur
Image utilisateur
 
Hors ligne BoudBoulMan # Posté le 03/07/2008 à 10:47:17
Saucisse transgénique
Avatar
Groupe : Membres
Pour ceux qui voudrait utiliser des caractères accentués dans leur tableau de statistiques, comme par exemple:
Code : Console
+----------------------------------------+--------+
| Nombre de caractères                   |       0|
| Nombre de caractères (hors espace)     |       0|
| Nombre de mots                         |       0|
| Nombre de paragraphes                  |       0|
+----------------------------------------+--------+

Et si vous utilisez le manipulateur setw pour cela, sachez que les caractères accentués comptent pour deux caractères et les caractères ajoutés ne rempliront plus le même espace.

Ici par exemple, il faut normalement spécifier setw(40) pour remplir correctement la colonne de gauche mais pour "Nombre de caractères" et "Nombre de caractères (hors espace)", il faut indiquer setw(41) par le fait qu'il y a un caractère accentué qui "occupe" une place de plus.

Voilà, si ça peut aider certains qui auront ce problème.
Édité le 03/07/2008 à 10:48:17 par BoudBoulMan
Hors ligne Hiura # Posté le 03/07/2008 à 13:02:10
Avatar
Groupe : Membres
Citation : kudo2
on peut essayer de le faire avec Qt ou seulement avec la console ?
merci
Non pas de Qt. Sinon ce serait indiqué.
 
Hors ligne lmghs # Posté le 03/07/2008 à 13:51:07
Groupe : Membres
@BoudBoulMan, c'est parce que tu dois bosser en utf-8.
 
Hors ligne Nanoc # Posté le 03/07/2008 à 18:06:48
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
@moa3788: Tous les caractères affichables comptent ensuite les autres comme \t, \n ,... vont dans la catégorie "espaces". Je ne sais pas exactement comment comptent OOo et Word, c'était juste pour donner une idée.

@kudo2: Tu peux faire une interface Qt si ça t'intéresse. Néanmoins la correction n'en aura pas et il ne sert donc à rien d'envoyer ton code dans ce cas, car il ne pourra servir de correction.

@Bouboulman: Ca dépend des paramètres de ta console en fait.
 
Hors ligne BoudBoulMan # Posté le 03/07/2008 à 21:15:29
Saucisse transgénique
Avatar
Groupe : Membres
Ok, merci pour la précision.

Et également, ce n'est pas très grave si on utilises la classe ifstream et que donc il y a quelques problèmes au niveau du comptage de caractères de fichiers utf-8?
Hors ligne Nanoc # Posté le 03/07/2008 à 21:24:52
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
Non,non. C'est le principe qui compte. L'affichage on s'en fout un peu. (Mais pas trop quand même)
 
Hors ligne Nanoc # Posté le 05/07/2008 à 11:51:42
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres

Solution du mois de juin 2008



Bonjour tout le monde ! Il est temps que je dévoile une solution pour l'exercice du mois de juin . Vous avez été 22 à m'envoyer une solution. Parmi celles-ci plusieurs ne correspondaient pas exactement à la donnée et d'autres étaient trop complexes (même si correctes) pour faire office de corrigé.
J'ai finalement retenu la solution de lanfeusst.

Solution complète



Cet exercice avait principalement deux difficultés, la première consistait à lire un fichier texte ligne par ligne. La deuxième était de gérer proprement tous les cas donnés dans l'algorithme RLE.

Lecture ligne-par-ligne:

Il fallait pour cela se rappeler de la fonction getline() et de sa syntaxe un peu inhabituelle.

Code : C++
1
getline(flux, string);


Il fallait ègalement se souvenir que cette fontion renvoit un booléen indiquant si la lecture peut continuer. Ceci est très pratique pour savoir quand se termine le fichier (ou si un erreur survient)comme cela est fait dans le code source ci-dessous.

Compression des lignes:

Plusieurs méthodes sont ici possibles, la plus simple étant de parcourir la chaîne de caractère et de créer une nouvelle chaine avec les modifications nécessaires comme donné dans la donnée de l'exercice.
On pouvait également utiliser un itérateur ou ne pas créer une nouvelle chaine de caractère. Tous ces choix sont valables.

Gestion des exceptions


Gérer les exceptions dans cet exercice était un petit plus. Le code ci-dessous utilise des strings comme exception. Cette approche est valable mais ne permet pas de récupérer les exceptions standards qui pourraient être lancées par la bibliothèque standard.
Le mieux aurait été de créer sa propre classe d'exception dérivée de la classe standard ou alors d'utiliser les eceptions standards comme std::runtime_error par exemple.

Je vous laisse avec le code source. Si vous aves des questions, n'hésitez-pas, je complèterai en conséquence.

Programme complet



Voici le code source qu'il a proposé.

main.cpp :
Secret (cliquez pour afficher)

Code : C++
  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
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
#include <iostream>

using namespace std;

int gereArguments(char argc,char *argv[]);
void afficheAide();
void compression(const string&,char, const string&);
void decompression(const string&,char, const string&);

int main(char argc,char *argv[])
{
    bool retour;
    /* on envoit les arguments à la fonction pour qu'elle appelle les fonctions de compressions
       ou de décompression :                                                                   */
    try
    {
        retour = gereArguments(argc,argv);
    }

    catch (const string& exceptions)// on récupère les exceptions et on les affiche
    {
        cerr<<exceptions;
        retour = EXIT_FAILURE;
    }
    return retour;
}


int gereArguments(char argc,char *argv[])
{
    if (argc < 3)// si il n'y pas assez d'arguments
    {
        afficheAide();
        return(EXIT_FAILURE);
    }


    string CheminFichier = argv[argc-1];
    string Argument1 = argv[1];// On récupère l'argument de la compression ou décompression

    char flag = '@';
    string FichierResultat = CheminFichier;
    if (argc>3)
    {
        string Argument2 = argv[2];
        if (Argument2.substr(0,2)=="-f")// si l'utilisateur veut préciser le flag
        {
            if (Argument2.size()>4)
                throw string("Le flag ne doit être constitué que d'un seul caractère.\n");
            else if (Argument2.size()<4)
            {
                afficheAide();
                return EXIT_FAILURE;
            }
            flag = Argument2[3];
            if (flag=='3'||flag=='4'||flag=='5'||flag=='6'||flag=='7'||flag=='8'||flag=='9')
                throw string("Le flag ne peut pas être un chiffre supérieur à 2.\n");// pour éviter des problèmes à la décompression
            if (argc==5) // si l'utilisateur veut aussi préciser la destination
            {
                string Argument3 = argv[3];
                if (Argument3.substr(0,2)=="-n"&&Argument3.size()>3)
                    FichierResultat = Argument3.substr(3,Argument3.size());
                else
                {
                    afficheAide();
                    return EXIT_FAILURE;
                }
            }
            else if (argc>5)
            {
                afficheAide();
                return EXIT_FAILURE;
            }
        }
        else if (Argument2.substr(0,2)=="-n"&&Argument2.size()>3) // si l'utilisateur veut seulement préciser la destination
            FichierResultat = Argument2.substr(3,Argument2.size());
        else
        {
            afficheAide();
            return EXIT_FAILURE;
        }
    }
    if (Argument1=="-c")
        // On compresse avec les options (changées ou pas par l'utilisateur)
        compression(CheminFichier,flag,FichierResultat);
    else if (Argument1=="-d")
        // On décompresse avec les options (changées ou pas par l'utilisateur)
        decompression(CheminFichier,flag,FichierResultat);
    else
        afficheAide();

    return EXIT_SUCCESS;
}

void afficheAide()
{
    cout<<"Utiliser ce programme de cette manière :"<< endl<<endl<<
    "Pour la compression, utilisez le parametre -c"<<endl<<endl<<
    "Pour la décompression, utilisez le parametre -d"<<endl<<endl<<
    "Si vous voulez utiliser un flag spécifique :"<<endl<<"Utilisez le paramètre -f=\"flag\""
    "dans lequel vous remplacez flag par la lettre"<<endl<<"(Attention il est nécessaire"
    " d'utiliser le même flag pour la compression et la"<<endl<<"décompression)"<<endl<<endl<<
    "Si vous ne souhaitez pas écraser le fichier original(compressé ou décompressé) :"<<endl<<
    "Vous pouvez indiquer la destination en utilisant le paramètre -n=\"fichier_dest\""<<endl<<endl<<
    "Il est nécessaire d'indiquer le fichier à compresser ou à décompresser à la fin"<<endl<<endl<<
    "Exemple : RLE -c -f=\"&\" mon_fichier.txt"<<endl<<
    "Compresse le fichier \"mon_fichier.txt\" en utilisant le flag &"<<endl<<endl<<
    "RLE -d -n=\"fichier.decompr\" fichier.rle"<<endl<<
    "Décompresse le fichier \"fichier.rle\" dans \"fichier.decompr\" en utilisant"<<endl<<
    "le flag par défaut"<<endl<<endl;
}



compression.cpp :
Secret (cliquez pour afficher)

Code : C++
  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
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//gère la compression ainsi que la fonction de réecriture

#include <iostream>
#include <fstream>
#include <cstdio> //pour la suppression du fichier

using namespace std;

string transformePetit(const string&,char);
//Compresse une chaine de caractere selon les regles du RLE

void reecrit(const string&,const string&, const string&);
//Copie un fichier dans un autre et supprime le premier fichier

//-------------------------------------------------------------------------------------------------

void compression(const string& CheminACompresser,char flag, const string& CheminResultat)
{
    cout<< "compression en cours..."<<endl;

    // On ouvre les fichiers et on teste les ouvertures en lancant des exceptions si besoin
    ifstream FichierSource(CheminACompresser.c_str(), ios::in);

    if (FichierSource.fail())
        throw string("Impossible d'ouvrir le fichier à compresser :\n"+CheminACompresser+"\n");

    const string CheminACompresserTemp = CheminACompresser + ".rle.tmp"; //fichier temporaire qui sera supprimé à la fin
    ofstream FichierResultat(CheminACompresserTemp.c_str(), ios::out | ios::trunc);

    if (FichierResultat.fail())
        throw string("Impossible d'ouvrir le fichier dans lequel on veut compresser :\n");

    //Variables temporaires pour la compression
    string LigneActuelle, LigneConverti;
    unsigned int nombreDeCaractereAvant = 0, nombreDeCaractereApres = 0;
    unsigned int pourcentage = 0;

    // La boucle parcourt tout le fichier ligne par ligne
    while (getline(FichierSource,LigneActuelle))
    {
        // On compresse la ligne actuelle
        LigneConverti = transformePetit(LigneActuelle,flag);

        // On compte les caractères pour afficher le taux de compression
        nombreDeCaractereAvant += LigneActuelle.size();
        nombreDeCaractereApres += LigneConverti.size();

        // on inscrit la ligne compressée dans le fichier temporaire
        FichierResultat<<LigneConverti;

        if (!FichierSource.eof())// et on rajoute une ligne si on a pas atteint la fin du fichier
            FichierResultat<<endl;
    }

    // On calcule le pourcentage et on l'affiche
    cout<<"compression terminée sans erreur : ";
    pourcentage = static_cast<int>(nombreDeCaractereApres*100.0/nombreDeCaractereAvant);
    cout<<"Le fichier fait "<<pourcentage<<" % de sa taille originale."<<endl;
    
    //On gere le cas ou la compression a ete inefficace
    string Continuer = "O";

    if (pourcentage>100.0) // On affiche un message de confirmation
    {
        cout<<"Le taux de compression est mauvais, peut-être essayez vous de compresser"<<endl<<
        "un fichier déjà compressé ?"<<endl<<
        "Sinon il est peut-être nécessaire d'essayer avec un autre flag (option -f)"<<endl<<endl<<
        "Souhaitez vous continuez [O/n] ? ";
        cin >> Continuer;
    }
    
    //On ferme les deux fichiers
    FichierSource.close();
    FichierResultat.close();

    // On réecrit le contenu du fichier temporaire dans le fichier de destination et on supprime
    // le fichier temporaire                                                               
    reecrit(CheminACompresserTemp,Continuer, CheminResultat);
}

//-------------------------------------------------------------------------------------------------

string transformePetit(const string& LigneActuelle, char flag)
{
    char caractereActuel =' ', ancienCaractere=' ';
    int nombreDePresence = 0;
    string LigneConverti;

    // tant que la fin de la ligne n'est pas atteinte
    for (unsigned int i = 0;i<=LigneActuelle.size();i++)
    {
        if (i>=1)
            ancienCaractere = caractereActuel;

        caractereActuel = LigneActuelle[i];

        if (ancienCaractere==flag&&i>=1)// Si il y a un flag dans le texte
        {
            LigneConverti = LigneConverti + flag + flag;
            nombreDePresence = 1;
        }

        // Si le caractère actuel est le même que celui d'avant
        else if (ancienCaractere==caractereActuel&&i>=1&&nombreDePresence<9)
            nombreDePresence++;

        // Sinon si le nombre de présence est <= 2 on les affiche normalement
        else if (nombreDePresence<=2)
        {
            for (int j = 0;j<nombreDePresence;j++)
                LigneConverti+=ancienCaractere;
            nombreDePresence = 1;
        }

        // Si le nombre de présence est > 2 on les affiche compressés (nombre,flag,caractère)
        else
        {
            char nombre = nombreDePresence +48;
            LigneConverti = LigneConverti +nombre+ flag + ancienCaractere;
            nombreDePresence = 1;
        }
    }

    return LigneConverti;
}

//-------------------------------------------------------------------------------------------------

void reecrit(const string& FichierAReecrire,const string& continuer,const string& CheminResultat)
{
    if (continuer=="O"||continuer=="o")// Si l'utilisateur a continué
    {
        // On ouvre les fichiers et on vérifie les ouvertures en lancant des exceptions si besoin
        ifstream FichierSource(FichierAReecrire.c_str(), ios::in);
        ofstream FichierResultat(CheminResultat.c_str(), ios::out | ios::trunc);

        if (FichierSource.fail())
            throw string("Problème interne : fichier1\n");

        if (FichierResultat.fail())
            throw string("Problème interne : fichier2\n");

        string LigneActuelle;
        // on recopie tout le fichier temporaire dans le fichier définitif
        while (getline(FichierSource,LigneActuelle))
        {
            FichierResultat<<LigneActuelle;
            if (!FichierSource.eof())
                FichierResultat<<endl;
        }
        FichierSource.close();
        FichierResultat.close();

    }

    // Suppression du fichier temporaire 
   remove(FichierAReecrire.c_str());

}


decompression.cpp :
Secret (cliquez pour afficher)

Code : C++
  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
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// gère la decompression

#include <iostream>
#include <fstream>

using namespace std;

string transformeGrand(const string&,char);
//Decompresse une chaine de caractere selon les regles du RLE

void reecrit(const string&,const string&,const string&);
//Copie un fichier dans un autre et supprime le premier fichier

void decompression(const string& CheminADecompresser,char flag, const string& CheminResultat)
{
    cout<< "décompression en cours..."<<endl;

    // On ouvre les fichiers et on teste les ouvertures en lancant des exceptions si besoin
    ifstream FichierSource(CheminADecompresser.c_str(), ios::in);

    if (FichierSource.fail())
        throw string("Impossible d'ouvrir le fichier à compresser :\n");

    const string CheminADecompresserTemp = CheminADecompresser + ".rle.tmp";
    ofstream FichierResultat(CheminADecompresserTemp.c_str(), ios::out | ios::trunc);

    if (FichierResultat.fail())
        throw string("Impossible d'ouvrir le fichier dans lequel on veut decompresser :\n");

    //Variables temporaires pour la decompression
    string LigneActuelle, LigneConverti;

    // La boucle parcourt tout le fichier ligne par ligne
    while (getline(FichierSource,LigneActuelle))
    {
        // On décompresse la ligne
        LigneConverti = transformeGrand(LigneActuelle,flag);

        // On l'inscrit dans le fichier temporaire
        FichierResultat<<LigneConverti;
        if (!FichierSource.eof())
            FichierResultat<<endl;
    }

    cout<<"décompression terminée sans erreur"<<endl;

    FichierSource.close();
    FichierResultat.close();

    // On réecrit le fichier temporaire dans le fichier de destination
    reecrit(CheminADecompresserTemp,"0", CheminResultat);
}
string transformeGrand(const string& LigneActuelle,char flag)
{

    string LigneConverti;

    // On utilise ces variables pour ne pas se casser la tête avec des LigneActuelle[...] à répétition
    char prochainCaractere =' ', caractereActuel =' ', dernierCaractere =' ', avantDernierCaractere =' ', apresProchainCaractere =' ';
    int nombreDePresence = 0, nombreDeFlagSuccessif = 0;
    unsigned int finDeLigne = LigneActuelle.size();
    bool pasFlag = false;


    for (unsigned int i = 0;i<LigneActuelle.size();i++)
    {
        // On n'initialise les variables que si on n'a le droit de le faire (attention aux début et fin de ligne)
        if (i>=2)
            avantDernierCaractere = dernierCaractere;
        if (i>=1)
            dernierCaractere = caractereActuel;
        caractereActuel = LigneActuelle[i];
        if (i+1<=finDeLigne)
            prochainCaractere = LigneActuelle[i+1];
        if (i+2<=finDeLigne)
            apresProchainCaractere = LigneActuelle[i+2];

        // Permet de vérifier que le fichier a déjà été compressé (test à la fin)
        if (caractereActuel==flag)
            nombreDeFlagSuccessif++;
        else
            nombreDeFlagSuccessif = 0;

        // Si les caractères ont été compressés sous la forme |nombre|flag|caractere|
        if (dernierCaractere ==flag&&caractereActuel!=flag&&avantDernierCaractere!=flag&&i>=2)
        {
            nombreDePresence = avantDernierCaractere;
            nombreDePresence-=48;

            for (int j = 0;j<nombreDePresence;j++)
                LigneConverti+=caractereActuel;
        }
        // Le caractère n'est pas écrit sous forme compressé:

        // Si le caractère est entouré de 2 autres caractères non flag
        else if ((dernierCaractere!=flag&&caractereActuel!=flag&&prochainCaractere!=flag&&i>=1)||
                 // Ou si il est en début de ligne et que le prochain caractère n'est pas un flag
                 (caractereActuel!=flag&&prochainCaractere!=flag&&i==0)||
                 // Ou si il est en début de ligne et que les 2 prochains caractères sont des flags
                 (caractereActuel!=flag&&prochainCaractere==flag&&apresProchainCaractere==flag&&i==0)||
                 // Ou si il est suivi d'au moins 2 flags et précédé par un caractère normal
                 (prochainCaractere==flag&&apresProchainCaractere==flag&&caractereActuel!=flag&&dernierCaractere!=flag&&i>=1&&i+2<=finDeLigne)||
                 // Ou l'inverse
                 (avantDernierCaractere==flag&&dernierCaractere==flag&&caractereActuel!=flag&&prochainCaractere!=flag&&i>=2&&i+1<=finDeLigne)||
                 // Ou si il est précédé par 2 flags et suivi par 2 flags
                 (avantDernierCaractere==flag&&dernierCaractere==flag&&caractereActuel!=flag&&prochainCaractere==flag&&apresProchainCaractere==flag&&i>=2&&i<=finDeLigne))
        {
            LigneConverti+=caractereActuel;
        }
        // Si il y a 2 flags de suite ou plus :
        else if (caractereActuel==flag&&dernierCaractere==flag&&i>=1)
        {
            if (pasFlag)// Si on ne vient pas d'en écrire un
            {
                // On l'écrit
                LigneConverti +=flag;
                pasFlag = false;
            }
            else // Si on vient d'en écrire un
                pasFlag = true;
        }

        else
        {
            pasFlag = true;
            if (nombreDeFlagSuccessif%2==1&&nombreDeFlagSuccessif!=1) // On vérifie le nombre de flags successifs
            {
                string StrFlag;
                StrFlag += flag;
                throw string("Le fichier n'avait pas été compressé ou avait été compressé avec un flag différent\n"
                             "de celui-ci ("+StrFlag+"), ou a été corrompu par la suite.\nAnnulation.\n");
            }
        }
        // On vérifie qu'il n'y a pas plus de 2 caractères identiques
        if (dernierCaractere==caractereActuel&&caractereActuel==prochainCaractere&&i>=1&&dernierCaractere!=flag&&i>=1&&i+1<=finDeLigne)
        {
            // Il est aussi possible qu'il y en est 3 si le premier est précédé par un flag :
            // Si il y en a 3 mais que le premier n'est pas précédé par un flag :
            if (i>=3&&avantDernierCaractere==dernierCaractere&&LigneActuelle[i-3]!=flag)
            {
                // On envoie une exception avec le flag utilisé
                string StrFlag;
                StrFlag += flag;
                throw string("Le fichier n'avait pas été compressé ou avait été compressé avec un flag différent\n"
                             "de celui-ci ("+StrFlag+"), ou a été corrompu par la suite.\nAnnulation.\n");
            }
        }
    }
    return LigneConverti;

}


Il me semble que les commentaires et les noms de variables situés dans le code devrait permettre de comprendre les étapes un peu plus complexes de l'algorithme. Si ce n'est pas le cas, dites-le et j'en ajouterai


Remarques sur les codes reçus