Envoyé par
joffrey575
Pour le deuxième argument je n'ai pas bien saisi ce que veux dire expression de type classe.
>> et << sont des opérateurs binaires (comme '+', '-', etc..); ils prennent 2 paramètres : 1 à gauche et 1 à droite de l'opérateur. Le 1er paramètre est celui de gauche, le 2eme est celui de droite.
std::istream& operator>>(std::istream& gauche, Line& droite) { /* ... */ }
Un opérateur est une fonction qui peut être appelée avec une syntaxe particulière
1 2 3 4 5 6
| Line l;
std::cout << l;
// équivalent à
Line l;
operator<<(std::cout, l); |
Ou dans le cas d'une addition, si c'est plus clair
1 2 3 4 5
| int i, j;
i + j;
// équivalent à
operator+(i, j); |
Envoyé par
joffrey575
La surcharge de l'opérateur est bien la syntaxe suivante :
?
Oui, note que les paramètres sont fixes (avec T le type qui t'intéresse)
1 2 3 4
| std::istream& operator>>(std::istream& is, T& obj) {
// lecture du flux pour donner les bonnes valeurs à obj;
return is; // on retourne le flux pour pouvoir chainer les appels
} |
Envoyé par
joffrey575
Par contre, en début du fichier.txt j'ai mis d'autres renseignements. La structure est fixe mais chaque valeur se trouve à des positions différentes bien connu. Je suppose ne pas connaitre la longueur des valeurs pour permettre une utilisation plus large.
Comment faire pour traiter cette partie non-régulière et la partie régulière?
Peut être est-il possible de se servir du curseur de position ou alors du fait qu'avant chaque valeur se trouve le caractère ' : ' ! Mais la je reste sans voix pour le moment.
Il te faut une façon de délimiter ces 2 parties :
- soit tu sais que l'entête va faire un nombre précis de lignes (ou caractères)
- soit tu marques une limitation entre l'entête et la partie régulière (un caractère, ou chaine de caractère particulière).
Pour ça il peut être pratique d'avoir une classe représentant les données de ton fichier, contenant le header et les données "normales".
Par exemple si ton fichier ressemble à
1 2 3 4 5
| foo 42
bar "abc"
fin_entete
1500.000000 336.668600
2300.000000 6.668600 |
Tu peux avoir un truc du genre
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
| struct Line {
double a, b;
};
std::istream& operator>>(std::istream& is, Line& line) {
return is >> line.a >> line.b;
}
std::ostream& operator<<(std::ostream& os, Line const& line) {
return os << line.a << " " << line.b;
}
struct Data {
std::map<std::string, string> header;
std::vector<Line> lines;
static Data fromFile(std::string& fileName) {
Data d;
std::ifstream is(fileName);
std::string headerLine;
bool headerDone = false;
while(is) { // lecture du header
std::getline(is, headerLine);
if(headerLine == "fin_header") {
break;
}
std::string key, value;
std::sstream ss;
ss << headerLine;
ss >> key >> value; // on recupère le coucle clef / valeur de chaque ligne
d.header.insert(std::make_pair(key, value));
}
// puis le bloc de données "normales"
Line l;
while(is >> l) {
d.lines.push_back(l);
}
return d;
}
private:
Data() { }
};
Data d(Data::fromFile("data.txt"));
// affichage
for(auto const& l: d.lines) {
std::cout << l << '\n';
} |
edit : hum... tu as complètement édité tes 2 posts entre temps.
Pour les erreurs, lire un cours de C++ à partir de 0 t'aidera : où définir un fonction (la réponse n'est pas dans le corp d'une autre fonction ^^"), rôle des includes etc... C'est vraiment les bases qu'il te manque.
Pour les range based loops, active c++11 sur ton compilo.
Partager