Pregunta

otra solicitud lo siento .. Ahora mismo estoy leyendo los tokens uno por uno y funciona, pero quiero saber cuándo hay una nueva línea ...

si mi archivo contiene

Hey Bob
Now

debería darme

Hey
Bob
[NEW LINE]
NOW

¿Hay alguna manera de hacer esto sin usar getline?

¿Fue útil?

Solución

Sí, el operador > > cuando se usa con una cadena, lea las palabras separadas por "espacios en blanco". Un "espacio en blanco" incluye una pestaña de espacio y nuevos caracteres de línea.

Si desea leer una línea a la vez, use std :: getline ()
La línea puede ser tokenizada por separado con una secuencia de cadena.

std::string   line;
while(std::getline(std::cin,line))
{

    // If you then want to tokenize the line use a string stream:

    std::stringstream lineStream(line);
    std::string token;
    while(lineStream >> token)
    {
        std::cout << "Token(" << token << ")\n";
    }

    std::cout << "New Line Detected\n";
}

Pequeña adición:

Sin usar getline ()

Entonces, realmente desea poder detectar una nueva línea. Esto significa que la nueva línea se convierte en otro tipo de token. Así que supongamos que tiene palabras separadas por 'espacios en blanco' como tokens y nueva línea como su propio token.

Entonces puede crear un tipo de Token.
Luego, todo lo que tiene que hacer es escribir los operadores de flujo para un token:

#include <iostream>
#include <fstream>

class Token
{
    private:
        friend std::ostream& operator<<(std::ostream&,Token const&);
        friend std::istream& operator>>(std::istream&,Token&);
        std::string     value;
};
std::istream& operator>>(std::istream& str,Token& data)
{
    // Check to make sure the stream is OK.
    if (!str)
    {   return str;
    }

    char    x;
    // Drop leading space
    do
    {
        x = str.get();
    }
    while(str && isspace(x) && (x != '\n'));

    // If the stream is done. exit now.
    if (!str)
    {
        return str;
    }

    // We have skipped all white space up to the
    // start of the first token. We can now modify data.
    data.value  ="";

    // If the token is a '\n' We are finished.
    if (x == '\n')
    {   data.value  = "\n";
        return str;
    }

    // Otherwise read the next token in.
    str.unget();
    str >> data.value;

    return str;
}
std::ostream& operator<<(std::ostream& str,Token const& data)
{
    return str << data.value;
}


int main()
{
    std::ifstream   f("PLOP");
    Token   x;

    while(f >> x)
    {
        std::cout << "Token(" << x << ")\n";
    }
}

Otros consejos

No sé por qué piensas que std :: getline es malo. Todavía puede reconocer nuevas líneas.

std::string token;
std::ifstream file("file.txt");
while(std::getline(file, token)) {
    std::istringstream line(token);
    while(line >> token) {
        std::cout << "Token :" << token << std::endl;
    }
    if(file.unget().get() == '\n') {
        std::cout << "newline found" << std::endl;
    }
}

Esta es otra forma genial y mucho menos detallada que encontré para tokenizar cadenas.

vector<string> vec; //we'll put all of the tokens in here 
string token;
istringstream iss("put text here"); 

while ( getline(iss, token, '\n') ) {
       vec.push_back(token);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top