Y a-t-il un itérateur C++ qui peut itérer sur une ligne de fichier par ligne?

j'aimerais obtenir un itérateur de type istream_iterator qui retourne chaque ligne du fichier sous forme de chaîne de caractères plutôt que chaque mot. Est-ce possible?

41
demandé sur thehouse 2010-02-18 23:04:42

5 réponses

EDIT: ce même truc a déjà été posté par quelqu'un d'autre dans un thread précédent .

Il est facile d'avoir des std::istream_iterator faites 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;
}
25
répondu Manuel 2017-05-23 12:10:33

la bibliothèque standard ne fournit pas d'itérateurs pour faire cela (bien que vous puissiez implémenter quelque chose comme ça vous-même), mais vous pouvez simplement utiliser la getline fonction (pas la méthode istream) pour lire une ligne entière depuis un flux d'entrée vers 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;
}
19
répondu Matteo Italia 2012-10-13 02:10:22

Voici une solution. L'exemple imprimer 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.

5
répondu Rexxar 2010-02-18 22:06:35

vous pourriez écrire votre propre itérateur. Il n'est pas difficile. Un itérateur est juste une classe qui est (pour parler simplement) l'incrément et * les opérateurs sont définis.

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

4
répondu Patrick 2010-02-18 20:11:32

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

du 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;
}

"151960920 d'entrée".txt:

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

sortie:

ahhhh test
bhhhh second test
2
répondu coelhudo 2010-02-18 21:57:48