2010-12-11 70 views
2

Après avoir lu Jerry Coffin la réponse à ce question J'ai copié-collé son code dans mon éditeur, et après quelques modifications mineures, il a compilé et exécuté comme il se doit.Lecture du fichier jusqu'à la ligne vide

Voici le code après les modifications:

#include <iostream> 
#include <string> 
#include <istream> 
#include <fstream> 

class non_blank { 
private: 
std::string data_; 

friend std::istream& operator>> (std::istream &is, non_blank &n) { 
    std::getline(is, n.data_); 

    if (n.data_.length() == 0) { 
    is.setstate(std::ios::failbit); 
    } 
    return is; 
} 

public: 
operator std::string() const { 
    return data_; 
} 
}; 


int main(int, char *[]) { 

non_blank line; 
std::ifstream ifs("teste.txt"); 

while(ifs >> line) { 
    //std::cout << line; <----- error 
    std::string s = line; 
    std::cout << s << std::endl; 
} 

return 0; 
} 
  • J'ai une erreur en essayant d'utiliser une variable non_blank dans une expression std::cout <<.... Ne devrais-je pas être capable d'utiliser une variable du type non_blank partout où j'utiliserais std :: string? N'est-ce pas le but de l'opérateur cast/conversion ?? answer

  • Pourquoi ne puis-je accéder à la variable privée string::data_ directement dans la définition de la operator >>?

Voici l'erreur que je suis:

..\main.cpp: In function `std::istream& operator>>(std::istream&, non_blank&)': 
..\main.cpp:21: error: invalid use of non-static data member `non_blank::data_' 
..\main.cpp:26: error: from this location 
+0

Je n'ai pas compris quelque chose dans votre question ni dans le code (parce que je ne connais pas très bien C++), mais, sur la base du titre (lire le fichier jusqu'à la ligne vide) voici mon idée: pourquoi ne pas lire? chaque personnage et le comparer à celui qui le précède? si elles sont toutes deux '\ n', vous avez rencontré une ligne vide. – BlackBear

+0

Le code est entièrement fonctionnel: lit un fichier, ligne par ligne, jusqu'à ce qu'il rencontre une ligne vide. Pour pouvoir compiler, je devais faire de petits changements. C'est pourquoi j'ai posé ces questions. – bruno

+0

oh .. désolé alors .. – BlackBear

Répondre

1

je ne devrais pas être en mesure d'utiliser une variable du type non_blank où je utiliser un std :: string? N'est-ce pas le porphyre de l'opérateur de casting?

Pas tout à fait. Si le compilateur vous voit faire quelque chose qu'il sait avoir besoin d'une chaîne std :: string, il peut appeler votre opérateur de conversion pour en obtenir un. Mais dans le cas de l'opérateur ostream < <, il n'a pas une seule fonction spécifique à appeler, mais plutôt beaucoup d'entre eux, tous différents et aucun correspondant exactement le type réel que vous voulez imprimer. Donc, il énumère un tas de candidats, dont aucun n'est assez fort. Vous devez définir un opérateur ostream < < pour votre type afin de le faire imprimer comme il se doit. En ce qui concerne votre opérateur >>, vous devriez faire en sorte que ce ne soit pas un membre de votre classe. Déclarez-le comme un ami dans la déclaration de classe si vous le devez, mais écrivez la fonction elle-même à l'extérieur.

+0

Merci. En ce qui concerne l'opérateur >>, pourquoi devrais-je le définir en dehors de la classe, est-ce une "convention de code"? Et enfin, est-ce la raison pour laquelle je ne peux pas accéder aux variables de classe directement dans la définition de l'opérateur le fait que l'opérateur >> n'est pas une fonction membre? – bruno

+0

Il est certainement classique de définir les opérateurs de flux en dehors de la classe elle-même, car ils ne sont pas des fonctions membres. En ce qui concerne les raisons pour lesquelles vous ne pouvez pas accéder aux membres, essayez d'abord de déplacer la fonction à l'extérieur, puis voyez si cela fonctionne (en gardant bien sûr la déclaration d'ami dans la classe, bien sûr). –