Problème fonction C++

Résolu
Khornaaig Messages postés 5 Date d'inscription lundi 9 avril 2018 Statut Membre Dernière intervention 12 avril 2018 - Modifié le 9 avril 2018 à 13:03
Khornaaig Messages postés 5 Date d'inscription lundi 9 avril 2018 Statut Membre Dernière intervention 12 avril 2018 - 12 avril 2018 à 10:48
Bonjour,
j'ai un problème pour la réalisation d'une fonction : je mets certaines variables en public mais je n'y ai pas accès dans ma fonction main et je ne peux créer une autre fonction qui récupérera les données de mon tableau puisque erreur "variable non définie dans fichier.
Le code

.h
#ifndef CHARGEFICHIER_H_INCLUDED
#define CHARGEFICHIER_H_INCLUDED

#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>

{
public:
std::vector<std::string> calendrier;
int nbrelem;

public:
void Chargefichier();
};

#endif  //CHARGEFICHIER_H_INCLUDED


.cpp
#include "Chargefichier.h"

using namespace std;

void Chargefichier()

{
string ligne;
string mot;
 ifstream fichier( "Calen5Jours.txt", ios::in);  // on ouvre le fichier en lecture
 if(fichier)  // si l'ouverture a réussi
  {
   while (getline(fichier,ligne))   // on lit chaque ligne du fichier
    {
    istringstream enreg( ligne );   // on met chaque ligne dans "enreg"

    while ( getline( enreg, mot, ';' ) )    //tant que enreg n'est pas vide, on le découpe à chaque point-virgule
     {
     calendrier.push_back(mot);  //on stocke chaque mot dans un tableau
     }
    }
   nbrelem=calendrier.size()/7;    // on divise la totalité du tableau par 7 pour obtenir le nombre de lignes
fichier.close();
}
 else  // sinon
  cerr << "Impossible d'ouvrir le fichier !" << endl;
}


main.cpp
#include "Chargefichier.h"

using namespace std;

int main()
{
Chargefichier();
/* Affichage */
   for (int i=0; i < nbrelem; i++)
    {
    for (int j=0; j < 7; j++)
    cout << calendrier[i * 7 + j] << " ";
    cout << endl;
    }

cout << "TAILLE : "<< calendrier.capacity() << "     "  << calendrier[0] << "     "  << "NBR ELEMS : " << nbrelem << "     "  << calendrier[53] << '\n';
return (0);
}


merci par avance à ceux qui peuvent m'aider en m'expliquant un peu où sont les erreurs et les lacunes de conception

Cordialement, Khornaaig

7 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
9 avril 2018 à 13:10
Bonjour.

Il y a des soucis de syntaxe, c'est ça qui ne va pas. Est-ce que tu veux faire une classe ou une fonction ? Tu mélanges les deux syntaxes et ça ne peux pas fonctionner. Soit tu fais une fonction simple, et il n'y a pas de notion de "public" ou de visiblité, soit tu fais une classe, et alors là, il manque plein de chose (le nom de le classe, le prefix de classe au niveau de la fonction, etc...).

Je t'invite à regarder comment écrire une fonction (ou une classe) sur un cours de C++. Actuellement tu n'as pas un problème technique, mais un problème de cours.

Quelques petits conseils:
- Nomme tes fichiers .hh/.cc ou .hpp/.cpp, le .h est plutôt pour du C.
- Evite les using namespace, c'est assez crade, voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace/
- Le .close n'est pas nécessaire (l'objet ferme le fichier à sa destruction)
- Parenthèse non nécessaire sur le return: return (0) peut s'écrire directement return 0.
- Essaie d'écrire en anglais, si tu le peux (sinon ce n'est pas très grave).

N'hésite pas à poser des questions et ton code modifié, si tu as besoin de plus d'aide :).
0
Khornaaig Messages postés 5 Date d'inscription lundi 9 avril 2018 Statut Membre Dernière intervention 12 avril 2018
9 avril 2018 à 14:12
Merci pour ta réponse, effectivement j'ai encore de gros problème de concepts, mais le net regorge de tutos qui sont tous sensiblement les mêmes, difficile de trouver des réponses précises à ses questions sans les forums,
effectivement, je souhaitais créer une fonction seule (je pense qu'une classe, ici, serait inutile) mais pour une autre fonction, j'ai besoin des valeurs du tableau ainsi que du nombre d'éléments, et je ne vois pas trop comment faire (j'aimerais éviter les variables globales) et ma fonction ne peut pas (il me semble ?) renvoyer les 2, donc comment avoir accès aux éléments de mon tableau vector?
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié le 10 avril 2018 à 17:20
Dans ce cas, on va conserver ce que tu as fait, mais on va changer le "design". On va faire en sorte que la fonction n'ait qu'un seul rôle, qui est de remplir ton tableau. Elle n'affichera rien à l'écran (ce n'est pas son rôle), mais retournera si elle a réussi l'opération.

Ca donnerait ceci (attention je n'ai pas testé, je le fais de tête):

LoadCalendar.hh
#ifndef LOADCALENDAR_HH
#define LOADCALENDAR_HH

#include <vector>
#include <string>

bool loadCalendar(const std::string& filename, std::vector<std::string>& calendar);

#endif  // LOADCALENDAR_HH


LoadCalendar.cc
#include "LoadCalendar.hh"
#include <sstream>
#include <fstream>

bool loadCalendar(const std::string& filename, std::vector<std::string>& calendar)
{
  std::ifstream file(filename.c_str());
  if (!file)
    return false;

   std::string line;
   while (std::getline(file, line))
   {
     std::istringstream row(line);
     std::string word;
     while (std::getline(row, word, ';'))
       calendar.push_back(word);
    }

  return true;
}


main.cc
#include "LoadCalendar.hh"

int main()
{
  const std::string filename = "Calen5Jours.txt";
  std::vector<std::string> calendar;
  if (!loadCalendar(filename, calendar))
  {
    std::cout << "Can't open " << filename << std::endl;
    return 1;
  }

  for (int i = 0; i < calendar.size(); ++i)
  {
    for (int j = 0; j < 7; ++j)
      std::cout << calendar[i * 7 + j] << " ";
    std::cout << std::endl;
  }

  return 0;
}


0
Khornaaig Messages postés 5 Date d'inscription lundi 9 avril 2018 Statut Membre Dernière intervention 12 avril 2018
9 avril 2018 à 14:53
Ok je regarde tout ça et te recontacte, j'aime bien comprendre le code que je recopie, et n'ai pas encore debons réflexes de codage
Cordialement,
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Khornaaig Messages postés 5 Date d'inscription lundi 9 avril 2018 Statut Membre Dernière intervention 12 avril 2018
11 avril 2018 à 09:00
Bonjour,
tout fonctionne, il fallait juste inclure iostream pour cout; par contre le programme plante après ouverture de la fenêtre, sinon j'aurai quelques petites questions:
- Pourquoi le nom de fichier est passé en constante?
- Pourquoi utiliser des pointeurs pour filename et calendar?
- Dans main, pourquoi redéclarer std::vector<std::string> calendar; est-ce que cela ne réinitialise pas la variable? Elle est déjà déclarée dans LoadCalendar.hh et celui-ci est inclus dans main, pourquoi main ne connait pas cette variable?

Merci par avance pour tes réponses, j'ai 56 ans, mes neurones commencent à être un peu collées, cordialement...
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié le 11 avril 2018 à 10:15
Par contre le programme plante après ouverture de la fenêtre


Ça dépend du format de ton fichier. J'ai traduit ton programme "ad hoc", et comme un moment tu fais: calendar[i * 7 + j], il suffit qu'il y ait trop peu d'éléments dans ton fichier et on sera "hors borne". Pour seulement deux lignes, il faut au moins 7 éléments, donc avoir un fichier comme ceci:
1;2;3
4

fera planter le programme.
Il manque une vérification du format du fichier, qui n'est pas codé dans l'exemple donné (s'assurer qu'il y a bien 7 éléments par ligne et peut-être vérifier que chaque élément est valide).


Pourquoi le nom de fichier est passé en constante?

Simple habitude, j'aurais tout aussi bien pu le mettre directement comme ceci: loadCalendar("Calen5Jours.txt", calendar);
Le mieux étant de le rendre sélectionnable par l'utilisateur.


Pourquoi utiliser des pointeurs pour filename et calendar?

Pour deux raisons différentes:
- Pour filename, pour éviter de copier une string pour rien (le & permet de passer l'objet string filename par référence au lieu de passer par copie). On pourrait remplacer "const std::string& filename" par "std::string filename", ça fonctionnerait aussi (mais il y aurait une copie pour rien).
- Pour calendar, ce n'est pas tant pour éviter une copie, mais pour surtout faire en sorte que ce soit cet objet calendar qui soit modifié et non sa copie (ce qui ne servirait à rien). Si on retire le &, alors le calendar sera copié, sa copie modifiée, puis jetée (détruite au sortir de la fonction). Le "vrai" calendar ne sera pas affecté. Essaie de retirer le &, et tu verras que calendar sera toujours vide.

Dans main, pourquoi redéclarer std::vector<std::string> calendar; est-ce que cela ne réinitialise pas la variable? Elle est déjà déclarée dans LoadCalendar.hh et celui-ci est inclus dans main, pourquoi main ne connait pas cette variable?


Attention, ne pas confondre déclaration et variable. Le seul et unique endroit où le vecteur est créé, c'est dans le main. Les autres endroits ne font que dire: voici le type auquel je m'attends.

Exemple déclaration: void function(int a);
Exemple variables: int a; int b;
Exemple utilisation de la fonction déclarée: function(a); function(b);

A noter que l'argument de la fonction et le nom de la variable ne sont pas liés (on n'est pas obligé de les appeler de la même manière).

0
Khornaaig Messages postés 5 Date d'inscription lundi 9 avril 2018 Statut Membre Dernière intervention 12 avril 2018
12 avril 2018 à 10:48
Bonjour cptpingu,

Merci pour ta patience et tes explications, je vais un peu tester et essayer d'assimiler tout cela et clore le sujet j'ai tellement de questions qu'il vaut mieux que je recrée un sujet à chacune,

Encore merci pour ton aide cordialement, Khornaaig
0
Rejoignez-nous