Me gustaría obtener un iterador estilo istream_iterator que devuelve cada línea del archivo como una cadena en lugar de cada palabra. es posible?¿Hay un iterador de C++ que pueda iterar sobre un archivo línea por línea?
Respuesta
EDIT: Este mismo truco que ya fue publicada por otra persona in a previous thread.
Es fácil tener std::istream_iterator
hacer lo que quiera:
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;
}
¿Heredar de std :: string aquí no infringe la Regla 35 del Estándar de codificación C++: "Evitar heredar de clases que no fueron diseñadas para ser clases base"? – thehouse
@thehouse - ¿Qué estándar de codificación quiere decir? No creo que haya nada de malo en utilizar una clase arbitraria como base siempre que no se use en un contexto polimórfico. Por ejemplo, el esquema de herencia en mi respuesta sería peligroso si hiciera cosas como 'cadena * ptr = nueva línea; delete ptr; 'pero ese no es el caso aquí – Manuel
@Manuel: Herb Sutter y Andrei Alexandrescu en su libro C++ Coding Standards afirman que" el uso de una clase independiente como base es un grave error de diseño y debe evitarse ". Siguen mencionando cadena explícitamente como una clase mala para heredar. Su argumento gira en torno al hecho de que tienes que hacer una serie de cosas para que la clase base funcione con seguridad y un conjunto de cosas contradictorias para hacer que las clases concretas sean seguras. – thehouse
La biblioteca estándar no proporciona iteradores para hacer esto (aunque puede implementar algo así por su cuenta), pero simplemente puede usar getline function (no el método istream) para leer una línea completa de una secuencia de entrada a una cadena de C++.
Ejemplo:
#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;
}
¿Maneja la diferencia en los caracteres eol para las diferentes plataformas (windows/unix/mac)? –
Esa diferencia ya se maneja en el objeto de flujo: cuando abre un archivo en modo texto (el valor predeterminado si no especifica el indicador 'ios :: binary') la secuencia convierte automáticamente el eol específico de la plataforma en' 'simple n'. –
estamos utilizando un COM istream que no trata los EOL de la misma manera. El análisis de dos archivos funcionó pero el análisis de un archivo UNIX (sin LF) provocó que se manejara como si fuera una línea grande. –
Se puede escribir su propio iterador. No es tan dificil. Un iterador es solo una clase en la que (hablando simplemente) se definen los operadores increment y *.
Mire http://www.drdobbs.com/cpp/184401417 para comenzar a escribir sus propios iteradores.
@thehouse: es posible que también desee comprobar 'boost :: iterator_facade', que implementa el concepto de iterador completo de STL en términos de algunas funciones básicas. –
Puede utilizar istreambuf_iterator en lugar de istream_iterator. No ignora los caracteres de control como 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*
salida:
ahhhh test
bhhhh second test
Aquí es una solución. El ejemplo imprime el archivo de entrada con @@ al final de cada línea.
#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();
}
Editar: Manuel ha sido más rápido.
@Rexxar - Es malo, lo borré y luego lo borré como wiki de la comunidad. Lo siento por eso. – Manuel
- 1. ¿Cómo puedo iterar sobre cin línea por línea en C++?
- 2. C++: ¿Cómo iterar sobre un texto en una std :: string línea por línea con STL?
- 3. La lectura de un archivo línea por línea en C#
- 4. Java: ¿por qué no puede iterar sobre un iterador?
- 5. ¿Cómo leer un archivo .gz línea por línea en C++?
- 6. Lea un archivo línea por línea
- 7. Iterar a través de un archivo línea por línea en AppleScript?
- 8. ¿Cómo puedo iterar sobre un conjunto/HashSet sin un iterador?
- 9. archivo Python iterador sobre un archivo binario con nuevos modismo
- 10. iterar manualmente una línea de un archivo | bash
- 11. Leyendo un archivo de texto en MATLAB línea por línea
- 12. leyendo un archivo de texto en R línea por línea
- 13. Leer un archivo de texto línea por línea en Qt
- 14. phantomjs javascript leer un archivo local línea por línea
- 15. Pasando por un archivo de texto línea por línea en C
- 16. ¿Cómo leo un archivo gzip línea por línea?
- 17. Leer un archivo línea por línea en Prolog
- 18. Leer un archivo línea por línea hacia atrás usando fseek
- 19. Bash bucle while que lee archivo línea por línea
- 20. Haskell: lea un archivo por línea
- 21. cómo iterar en reversa sobre un mapa en C++
- 22. C++: iterar sobre una lista de un tipo genérico
- 23. C# Iterar sobre Diccionario ordenado por valor
- 24. perl: iterar sobre un typeglob
- 25. iterador bidireccional sobre archivo/ifstream
- 26. Registre una clase C++ para que luego una función pueda iterar sobre todas las clases registradas
- 27. ¿Cómo puedo iterar sobre las propiedades de un archivo?
- 28. ¿Hay alguna manera de iterar sobre un diccionario?
- 29. Cómo leer línea por línea desde un área de texto
- 30. ¿Hay un IDE de PHP en línea?
Supongo que siempre puedes escribir el tuyo usando la función getline() como dijo Matteo Italia. –
Duplicado: http://stackoverflow.com/questions/1567082/how-do-i-iterate-over-cin-line-by-line-in-c/1567703 –
@Jerry: Ese hilo contiene la respuesta. Pero la pregunta es completamente diferente. – UncleBens