j'aimerai créer une fonction qui changerai le contenu d'un tableau. Or, je ne sais pas comment faire, càd qu'est que je doit écrire dans les arguments, de quel manière utiliser la fonction etc ... est ce que quelqu'un pourrait m'éclairer ?
Alors déjà j'ai besoin de deux dimension dans mon tableau et puis je ne sais pas ce qu'est std::vector etc. et encore moins les utiliser. Sinon comme IDE j'utilise code blocks. Et puis j'ai inclus <string> dans le header. Après, je ne comprend pas pourquoi tu dit que mon tableau "c'est du c".
Alors déjà j'ai besoin de deux dimension dans mon tableau et puis je ne sais pas ce qu'est std::vector etc. et encore moins les utiliser. Sinon comme IDE j'utilise code blocks. Et puis j'ai inclus <string> dans le header. Après, je ne comprend pas pourquoi tu dit que mon tableau "c'est du c".
Il faut se renseigner alors. Et changer de support, parce que tu apprends avec un cours bien obsolète.
Le type std::vector permet de faire les mêmes choses que les tableaux C comme dans ton code, mais en plus simple, plus sécurisé et bien plus pratique.
Ha ok car mon cours c'est justement celui proposé par open classroom donc franchement je vois ou est ce que je pourrais allez chercher un autre cours ...
Il faut savoir, en plus, que l'on évitera autant que faire se peut de transmettre un paramètre à une fonction dans l'espoir que cette fonction modifiera la donnée "pour la fonction appelante", parce que cela occasionnera un "effet de bord".
A choisir, on préférera toujours -- dans la mesure du possible, du moins -- ne fournir que des informations qui ne seront pas modifiées par la fonction appelée, ou, du moins dont les modifications apportées par la fonction appelée ne seront pas reportées vers la fonction appelante, et renvoyer si possible une donnée locale à la fonction appelée sous forme de valeur.
Par exemple, si on veut extraire un tableau de chaîne de caractères d'un fichier dont le nom peut varier, nous choisirons de préférence une forme proche de
std::vector<std::string> readFromFile(std::string const & filename){
std::vector<std::string> tab; // le tableau qui sera rempli
std::ifstream ifs{filename}; // le fichier à lire
/* si on n'arrive pas à ouvrir le fichier */
if(!ifs){
/* on ne peut pas aller plus loin, autant faire
* planter l'application "prorprement"
*/
throw std::runtime_error("unable to open file");
}
std:string temp; // la chaine de caractères utilisée pour
// l'extraction
/* tant qu'il y a des lignes à extraire */
while(std::getline(ifs, temp)){
/* on fait ce que l'on a à faire
}
return tab; // on renvoie le tableau rempli
}
qui pourra être utilisée sous la forme de
int main(){
auto tab = readFromFile("fichier.txt");
}
plutôt que d'avoir une fonction proche de
void readFromFile(std::string const & filename,
std::vector<std::string const & tab){
/* les grosses différences avec la version précédente
* sont que l'on utilise directement tab, qui est
* donné en paramètre
*
* et qu'on ne le renvoie pas à la fin de la fonction
*/
}
qui sera utilisée sous une forme proche de
int main(){
std::vector<std::string> tab;
readFromFile("fichier.txt", tab);
}
Nous aurions presque l'impression que cela revient au même, hein?
Et pourtant...
Réfléchissez à ce qui pourrait se passer si ces fonctions étaient appelées deux fois d'affilée. C'est idiot, je sais, mais l'utilisateur est un imbécile distrait, qui n'attend qu'une occasion de faire une connerie...
Et cela s'applique aussi bien à l'utilisateur des fonctions que je fournis qu'à l'utilisateur d'une application. En outre, la situation pourrait se présenter de manière beaucoup moins claire!
Voyons donc le résultat si nous passons le tableau en paramètre :
int main(){
std::vector<std::string> tab;
/* rempli une première fois le fichier: chouette!!!) */
readFromFile("fichier.txt", tab);
/* ajoute UNE DEUXIEME FOIS le contenu de fichier.txt
* dans tab
*/
readFromFile("fichier.txt", tab);
/* OUPPSS ... on a des données en double
* toutes les données extraites de fichier.txt
* sont présentes DEUX FOIS dans tab
*/
}
Et si on lit des fichiers différents, cela donnera quelque chose comme
int main(){
std::vector<std::string> tab;
/* rempli une première fois le fichier: chouette!!!) */
readFromFile("fichier.txt", tab);
/* ajoute le contenu d'AutreFichier dans tab
*/
readFromFile("AutreFichier.txt", tab);
/* OUPPSS ... les données de Fichier.txt et de
* AutreFichier.txt sont "mélangées dans le tableau
*/
}
Par contre, avec la première solution, il n'y a plus de problème, car, dans le pire des cas, l'utilisateur lira deux fois le même fichier, ce qui donnera quelque chose comme
int main(){
/* récupère le contenu du fichier */
auto tab = readFromFine("fichier.txt");
/* remplace le contenu du fichier par ..
* ce qu'il récupère lors d'une deuxième lecture
*/
tab = readFromFile("fichier.txt");
/* Au pire, il a perdu son temps */
}
Et, sinon, d'autres situations peuvent survenir, comme la lecture de plusieurs fichiers différents. Il y a alors deux solutions:
Soit, il récupère le tableau renvoyé par readFromFile dans la même donnée sous une forme proche de
int main(){
auto tab = readFromFile("Fichier.txt");
/*manipule les données de Fichier.txt */
tab = readFromFile("AutreFichier.txt");
/*manipule les données de AutreFichier.txt */
}
Il faudra juste espérer qu'il aura fini le traitement des données de Fichier.txt avant de lire celles que AutreFichier.txt contient.
Soit il récupère le tableau renvoyé dans des données différentes, sous une forme proche de
int main(){
auto tab = readFromFile("Fichier.txt");
auto autre = readFromFile("AutreFichier.txt");
/* un monde de possibilités */
}
Et là, un monde de possibilités s'offrent à lui
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Architecte logiciel - Software craftsmanship convaincu.
Architecte logiciel - Software craftsmanship convaincu.