# Algo Prog 2021-2022: TP3
###### tags: `algo` `bourg` `c++` `iut` `tp`
## Exercice 1
L'objectif de l'exercice est de récupérer des données contenues dans un fichier contenant la liste des communes de France, puis d'y rechercher des informations particulières.
1. Définir le type ``Commune`` comme une structure à trois champs: numéro de département (int), nom (char[50]), code postal (char[200]). Le code postal sera codé par une chaîne aussi longue que 200, car certaines villes en ont plusieurs. Par exemple, la ville du Havre en possède trois et son champ code postal sera codé de la façon suivante : 76600-76610-76620.
2. Ecrire une fonction ``void init(Commune& c, int dpt, const char n[], const char code[])`` qui initialise une Commune ``c`` à partir des valeurs passées en paramètres.
3. Ecrire une fonction ``void affiche(Commune& c)`` qui affiche les informations d'une commune de la façon suivante:
``département: 01 nom :Ambérieu-en-Bugey code postal : 01500.``
Pour les départements à un seul chiffre, vous prendrez soin de bien afficher le 0 en tête.
4. Ecrire un main où vous testez vos fonctions des questions précédentes en créant une commune, en l'initialisant puis en l'affichant.
:::spoiler
````C++
struct Commune {
char nom[50];
char code[200];
int dpt;
};
void init(Commune& c, char n[], char co[], int d) {
strcpy_s(c.nom, 50, n);
strcpy_s(c.code, 200, co);
c.dpt = d;
}
void affiche(Commune& c) {
if (c.dpt >= 10)
cout << "departement: " << c.dpt << " nom: " << c.nom << " code postal: " << c.code << endl;
else
cout << "departement: 0" << c.dpt << " nom: " << c.nom << " code postal: " << c.code << endl;
}
void main(){
Commune test;
init(test,"Bourg en Bresse","01000",1);
affiche(test);
}
````
:::
[Ici](https://perso.liris.cnrs.fr/eric.duchene/algo/villes.csv) vous trouverez un fichier nommé "villes.csv" qui contient la liste de toutes les communes de France avec sur chaque ligne: departement, nom et code postal (séparés par des points-virgules et des retours à la ligne entre chaque commune). Dans ce fichier, les villes ayant de multiples codes postaux sont représentées comme en question 1. Le nombre de lignes du fichier correspond donc au nombre de communes. Téléchargez ce fichier et placez-le dans votre répertoire de compilation.
5. Ecrire la fonction ``int compte_communes (const char nom_fichier[])`` qui retourne le nombre de communes présentes dans le fichier dont le nom est passé en paramètre. Testez-là dans votre main en affichant le nombre de villes du fichier villes.csv.
:::spoiler
````C++
int compte_communes(char nom_fichier[]) {
int cpt = 0;
char ligne[200];
ifstream entree(nom_fichier, ios::in);
if (!entree)
cout << " Probleme d'ouverture " << endl;
else {
while (!entree.eof()) {
entree.getline(ligne, 200);
cpt++;
}
entree.close();
}
return cpt - 1;
}
````
:::
7. Dans votre main, déclarez un tableau de communes dont la taille est égale au nombre de villes trouvé en question 5. Comme ce tableau est très grand, il faut augmenter la taille de la pile allouée par Visual : ``propriétés du projet -> Editeur de liens -> Système -> Taille de la reserve de pile -> 10 000 000``
8. Ecrire la fonction ``void importer(const char nom_fichier[], Commune tab[], int taille)`` qui stocke dans le tableau tab passé en paramètre les communes présentes dans le fichier. Le troisième paramètre correspond à la taille du tableau.
:::spoiler
````C++
void importer(char nom_fichier[], Commune tab[], int taille) {
int i = 0;
ifstream entree(nom_fichier, ios::in);
if (!entree)
cout << " Probleme d'ouverture " << endl;
else {
while (i<taille) {
char ligne[10];
entree.getline(ligne, 10, ';');
tab[i].dpt=atoi(ligne);
entree.getline(tab[i].nom, 100, ';');
entree.getline(tab[i].code, 200);
i++;
}
entree.close();
}
}
````
:::
10. Ecrire la fonction ``void affichetab(Commune tab[], int taille)`` qui affiche à l'écran les communes présentes dans le tableau de communes passé en paramètre.
:::spoiler
````C++
void affichetab(Commune tab[], int taille) {
int i;
for (i = 0; i<taille; i++) {
affiche(tab[i]);
}
}
````
:::
12. Testez les fonctions des questions 7 et 8 pour afficher le tableau de communes et vérifier qu'il correspond bien au fichier.
13. Ecrire une fonction ``void rechercheCP(Commune tab[], int taille)`` qui demande à l'utilisateur le nom d'une ville et affiche son ou ses codes postaux si cette ville est dans le tableau. N'oubliez pas que la fonction ``strcmp`` permet de comparer des chaines de caractères. Afficher un message particulier si la commune entrée par l'utilisateur ne se trouve pas dans le tableau. Le paramètre taille est la taille du tableau.
:::spoiler
````C++
void rechercheCP(Commune tab[], int taille) {
char nom[100];
int i;
cout << "veuillez entrer une ville à rechercher: ";
cin.getline(nom, 100);
for (i = 0; i<taille; i++) {
if (strcmp(nom, tab[i].nom) == 0) {
affiche(tab[i]);
return;
}
}
cout << "ville absente";
}
````
:::
15. Ecrire une fonction permettant de trier par ordre alphabétique votre tableau de communes. Vous utiliserez l'algorithme de tri de votre choix. Testez votre fonction en affichant les 20 premières communes dans l'ordre alphabétique. Cela peut prendre beaucoup de temps.
16. Ecrivez une fonction qui retourne le numéro du département qui possède le plus de communes, ainsi que le nombre moyen de communes par département.
17. Y a-t-il des communes qui ont le même nom mais des codes postaux différents ? Si oui, donnez la liste de ces communes et leur code postal.