Domanda
un'altra richiesta scusa .. In questo momento sto leggendo i token uno per uno e funziona, ma voglio sapere quando c'è una nuova riga ..
se il mio file contiene
Hey Bob
Now
dovrebbe darmi
Hey
Bob
[NEW LINE]
NOW
C'è un modo per farlo senza usare getline?
Soluzione
Sì, l'operatore > > se usato con una stringa, leggi le parole separate 'spazio bianco'. Uno "spazio bianco" include la scheda spazio e i caratteri di nuova riga.
Se vuoi leggere una riga alla volta usa std :: getline ()
La linea può quindi essere tokenizzata separatamente con un flusso di stringhe.
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";
}
Piccola aggiunta:
Senza usare getline ()
Quindi vuoi davvero essere in grado di rilevare una nuova riga. Ciò significa che newline diventa un altro tipo di token. Supponiamo quindi che le parole siano separate da "spazi bianchi" come token e newline come token.
Quindi è possibile creare un tipo di token.
Quindi tutto ciò che devi fare è scrivere gli operatori di flusso per 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";
}
}
Altri suggerimenti
Non so perché pensi che std :: getline
sia cattivo. Puoi ancora riconoscere le nuove righe.
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;
}
}
Questo è un altro modo interessante e molto meno prolisso in cui mi sono imbattuto per tokenizzare le stringhe.
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);
}