Fichas de archivos de lectura de C ++
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?
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);
}