57 votes

Existe-t-il un itérateur C ++ capable de parcourir un fichier ligne par ligne?

Je voudrais obtenir un itérateur de style istream_iterator qui renvoie chaque ligne du fichier sous forme de chaîne plutôt que chaque mot. Est-ce possible?

36voto

Manuel Points 5396

EDIT: Ce même truc a déjà été posté par quelqu'un d'autre dans un précédent fil de discussion .

Il est facile de demander à std::istream_iterator faire ce que vous voulez:

 namespace detail 
{
    class Line : std::string 
    { 
        friend std::istream & operator>>(std::istream & is, Line & line)
        {   
            return std::getline(is, line);
        }
    };
}

template<class OutIt>
void read_lines(std::istream& is, OutIt dest)
{
    typedef std::istream_iterator<detail::Line> InIt;
    std::copy(InIt(is), InIt(), dest);
}

int main()
{
    std::vector<std::string> v;
    read_lines(std::cin, std::back_inserter(v));

    return 0;
}
 

25voto

Matteo Italia Points 53117

La bibliothèque standard ne fournit pas d'itérateurs pour le faire (bien que vous puissiez implémenter vous-même quelque chose comme ça), mais vous pouvez simplement utiliser la fonction getline (pas la méthode istream) pour lire une ligne entière d'un flux d'entrée à une chaîne C ++ .

Exemple:

 #include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
    ifstream is("test.txt");
    string str;
    while(getline(is, str))
    {
        cout<<str<<endl;
    }
    return 0;
}
 

7voto

Rexxar Points 1076

Voici une solution. L'exemple imprime le fichier d'entrée avec @@ à la fin de chaque ligne.

 #include <iostream>
#include <iterator>
#include <fstream>
#include <string>

using namespace std;

class line : public string {};

std::istream &operator>>(std::istream &is, line &l)
{
    std::getline(is, l);
    return is;
}

int main()
{
    std::ifstream inputFile("input.txt");

    istream_iterator<line> begin(inputFile);
    istream_iterator<line> end;

    for(istream_iterator<line> it = begin; it != end; ++it)
    {
        cout << *it << "@@\n";
    }

    getchar();
}
 

Edit: Manuel a été plus rapide.

3voto

Patrick Points 12750

Vous pouvez écrire votre propre itérateur. Ce n'est pas si dur. Un itérateur est simplement une classe sur laquelle (en termes simples) l'incrément et les opérateurs * sont définis.

Consultez http://www.drdobbs.com/cpp/184401417 pour commencer à écrire vos propres itérateurs.

1voto

coelhudo Points 1375

Vous pouvez utiliser istreambuf_iterator au lieu de istream_iterator. Il n'ignore pas les caractères de contrôle comme istream_iterator.

code.cpp:

 #include <iterator>
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream file("input.txt");

    istreambuf_iterator<char> i_file(file);

    istreambuf_iterator<char> eof;

    std::string buffer;
    while(i_file != eof)
    {
        buffer += *i_file;
        if(*i_file == '\n')
        {
            std::cout << buffer;
            buffer.clear();
        }
        ++i_file;
    }

    return 0;
}
 

input.txt:

 ahhhh test *<-- There is a line feed here*
bhhhh second test *<-- There is a line feed here*
 

sortie:

 ahhhh test
bhhhh second test
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X