Chciałbym uzyskać iterator w stylu istream_iterator, który zwraca każdą linię pliku jako ciąg, a nie każde słowo. czy to możliwe?Czy istnieje iterator C++, który może iterować po pliku wiersz po linii?
Odpowiedz
EDIT: Ta sama sztuczka została już wysłana przez kogoś innego in a previous thread.
Łatwo jest mieć std::istream_iterator
rób co chcesz:
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;
}
Dziedziczenie z std :: string nie narusza tutaj reguły 35 standardu kodowania C++: "Unikaj dziedziczenia z klas, które nie zostały zaprojektowane jako klasy podstawowe"? – thehouse
@thehouse - Jaki standard kodowania masz na myśli? Nie sądzę, że jest coś złego w używaniu arbitralnej klasy jako bazy pod warunkiem, że nie jest używana w kontekście polimorficznym. Na przykład schemat dziedziczenia w mojej odpowiedzi byłby niebezpieczny, gdybym zrobił takie rzeczy jak 'string * ptr = new Line; delete ptr; 'ale nie w tym przypadku. – Manuel
@Manuel: Herb Sutter i Andrei Alexandrescu w swojej książce Standardy kodowania C++ stwierdzają, że" używanie samodzielnej klasy jako podstawy jest poważnym błędem konstrukcyjnym i należy go unikać ". Dodają, że ciąg jest jawnie zwany klasą złą dziedziczoną. Ich argumenty odnoszą się do faktu, że musisz wykonać jeden zestaw rzeczy, aby klasa bazowa mogła bezpiecznie pracować, oraz zestaw sprzecznych rzeczy, które zapewnią bezpieczeństwo klasom. – thehouse
W standardowej bibliotece nie jest to możliwe (choć można to zaimplementować samodzielnie), ale można po prostu użyć getline function (a nie metody istream), aby odczytać całą linię ze strumienia wejściowego do ciąg C++.
Przykład:
#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;
}
Czy obsługuje różnicę w znakach eol dla różnych platform (Windows/Unix/Mac)? –
Ta różnica jest już obsługiwana w obiekcie strumienia: gdy otwierasz plik w trybie tekstowym (domyślny, jeśli nie określisz flagi 'ios :: binary'), strumień automatycznie konwertuje specyficzny dla platformy eol na zwykły' \ n'. –
używamy komputera, który nie traktował EOL-ów tak samo. Analizowanie pliku DOS działało, ale parsowanie pliku UNIX (bez LF) powodowało, że był on obsługiwany tak, jakby był jedną dużą linią. –
można napisać własny iterator. To nie jest takie trudne. Iterator jest po prostu klasą, w której (po prostu mówiąc) przyrost i * operatory są zdefiniowane.
Spójrz na http://www.drdobbs.com/cpp/184401417, aby rozpocząć pisanie własnych iteratorów.
@thehouse: możesz również chcieć sprawdzić 'boost :: iterator_facade', które implementuje pełną koncepcję iteratora STL pod względem kilku podstawowych funkcji. –
Możesz użyć istreambuf_iterator zamiast istream_iterator. Nie ignoruje znaków sterujących, takich jak 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*
Wydajność:
ahhhh test
bhhhh second test
tu rozwiązanie. Przykład wypisuje plik wejściowy z @@ na końcu każdej linii.
#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 była szybsza.
@Rexxar - Mój zły, usunąłem go, a następnie skasowałem jako wiki społeczności. Przepraszam za to. – Manuel
- 1. Jak iterować po linii cin po linii w C++?
- 2. Poprawianie czytania pliku C++ wiersz po linii?
- 3. Iterowanie po linii pliku po linii w AppleScript?
- 4. Jak czytać wiersz pliku gzip po linii?
- 5. Czy istnieje wiersz poleceń UNIX do "mapowania" po linii?
- 6. Python iteruje po linii standardowej wiersz po linii używając input()
- 7. Zapisywanie stdout z podprocesu.Popen do pliku wiersz po linii
- 8. C++: Jak iterować tekst w linii std :: string po linii z STL?
- 9. Jak uzyskać wiersz do odczytu pliku po linii
- 10. Debugowanie - jak wykonać wiersz kodu po linii?
- 11. odczytu linii danych excel wiersz po wierszu z C# .net
- 12. C++ deque's iterator unieważniony po push_front()
- 13. Jak odczytać wiersz child_process po linii w pliku Node.js?
- 14. Python iterować po słowniku
- 15. C++ split string po linii
- 16. Czy mogę iterować po .NET4 MemoryCache?
- 17. Czy istnieje norma iterator cykliczny w C++
- 18. Brak linii po div?
- 19. Odczytaj linię pliku txt po linii
- 20. Nodejs - odczytaj wiersz po linii z pliku, wykonaj asynchroniczne działanie dla każdej linii i reusme
- 21. Efektywność czytania linii po linii w Pythonie
- 22. Iterowanie po liniach pliku
- 23. Jak korzystać z biblioteki Java JSch do odczytywania zdalnego pliku wiersz po linii?
- 24. Czytaj ostatni wiersz pliku w skrypcie bash podczas czytania wiersza pliku po linii
- 25. Przechowuj zawartość pliku tekstowego wiersz po wierszu do tablicy
- 26. Jak wydrukować wiersz słownika po linii w Pythonie?
- 27. Jak odczytać ze standardowego wejścia wiersz po linii?
- 28. Jak czytać wiersz tekstu po linii w obszarze tekstowym HTML?
- 29. Fscanf lub Fgets? Odczytywanie pliku wiersz po wierszu
- 30. Jquery dodać wiersz tabeli po wierszu, który dzwoni jquery
Myślę, że zawsze możesz napisać własną korzystając z funkcji getline(), jak powiedział Matteo Italia. –
Duplikat: http://stackoverflow.com/questions/1567082/how-do-i-iterate-over-cin-line-by-line-in-c/1567703 –
@Jerry: Wątek zawiera odpowiedź. Ale pytanie jest zupełnie inne. – UncleBens