2010-11-16 16 views
17

Tengo un texto en un objeto std :: string. El texto consiste en varias líneas. Quiero iterar sobre el texto línea por línea usando STL (o Boost). Todas las soluciones que se me ocurren parecen estar lejos de ser elegantes. Mi mejor enfoque es dividir el texto en los saltos de línea. ¿Hay una solución más elegante?C++: ¿Cómo iterar sobre un texto en una std :: string línea por línea con STL?

ACTUALIZACIÓN: Esto es lo que estaba buscando:

std::string input; 
// get input ... 
std::istringstream stream(input); 
std::string line; 
while (std::getline(stream, line)) { 
    std::cout << line << std::endl; 
} 

pensé que ya lo probé. Obtuve un error de compilación y lo arrojé. Para rápido!

+0

¿Está buscando "más elegante" como el foreach de C# "foreach (línea de cadena en líneas)"? ¿Qué has intentado exactamente? C++ podría sentirse "poco elegante" si está acostumbrado a los lenguajes dinámicos o de nivel superior, pero en C++ "elegante" nunca es solo para usted, por lo general tiene que programar la elegancia usted mismo. – Crisfole

+1

Puede que no sea * bastante * un duplicado exacto, pero es posible que también desee consultar: http://stackoverflow.com/questions/1567082/how-do-i-iterate-over-cin-line-by-line -in-c –

+0

Sería mejor responder a su propia pregunta en lugar de actualizarla. La actualización puede ser confusa para el futuro lector ... – Wolf

Respuesta

17

¿Por qué mantiene el texto en su archivo fuente? Guárdelo en un archivo de texto separado. Abrirlo con std :: ifstream e iterar sobre ella con while(getline(...))

#include <iostream> 
#include <fstream> 

int main() 
{ 
    std::ifstream fin("MyText.txt"); 
    std::string file_line; 
    while(std::getline(fin, file_line)) 
    { 
     //current line of text is in file_line, not including the \n 
    } 
} 

Alternativamente, si el texto tiene que estar en una línea std::string variable de lectura a línea con std::istringstream de una manera similar

Si su pregunta es cómo poner el texto lexially en su código sin usar +, tenga en cuenta que la cadena adyacente literales se concatenan antes de la compilación, por lo que podría hacer esto:

std::string text = 
    "Line 1 contents\n" 
    "Line 2 contents\n" 
    "Line 3 contents\n"; 
+5

Si realmente necesita trabajar con 'std :: string', puede envolverlo en' std :: stringstream' y aplicar la solución de Armen. –

+0

Si los datos ya son una cadena, podría simplemente usar 'std :: stringstream' de la misma manera. –

+0

@Space: edité :) –

3

Si quiere hacer un bucle line by line, como dirá, ¿por qué dividir el texto en los saltos de línea no sería exactamente lo que quiere?

No ha publicado el código que muestra cómo lo está haciendo, pero su enfoque parece correcto para lograr lo que dijo que quería. ¿Por qué se siente inferior?

+0

Parece el enfoque correcto para mí también. – Simone

+0

Prefiero usar alguna solución integrada de STL. Los finales de línea AFAIK dependen de la plataforma, por lo que me gustaría evitar esa solución si es posible. –

+0

@Fair: Eso (junto con su código actual) parece información que debería haber estado en la pregunta original. Es una preocupación válida y puede abordarse, pero solo si la aborda directamente :) – KevenK

8

uso Boost.Tokenizer :

std::string text("foo\n\nbar\nbaz"); 

typedef boost::tokenizer<boost::char_separator<char> > line_tokenizer; 
line_tokenizer tok(text, boost::char_separator<char>("\n\r")); 

for (line_tokenizer::const_iterator i = tok.begin(), end = tok.end(); 
    i != end ; ++i) 
    std::cout << *i << std::endl; 

impresiones

foo 
bar 
baz 

en cuenta que salta a través de líneas vacías, que pueden o no ser lo que quieres.

+0

¿No está utilizando boost :: tokenizer para algo que se puede hacer con getline sort-of como matar a un gorrión con un nuke? –

+0

Depende de lo que OP quiere hacer. Esta solución es bastante corta y produce un par de iteradores que se pueden entregar a los algoritmos STL. –

Cuestiones relacionadas