Вопрос
еще один запрос извините .. Прямо сейчас я читаю токены по одному, и это работает, но я хочу знать, когда появится новая строка.
если мой файл содержит
Hey Bob
Now
должен дать мне
Hey
Bob
[NEW LINE]
NOW
Есть ли способ сделать это без использования getline?
Решение
Да, оператор > > при использовании со строкой читать слова, разделенные пробелами. «Пробел» содержит пробел и символы новой строки.
Если вы хотите прочитать строку одновременно, используйте std :: getline ()
Строка может быть затем токенизирована отдельно с потоком строк.
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";
}
Небольшое дополнение:
Без использования getline ()
Итак, вы действительно хотите иметь возможность обнаруживать новую строку. Это означает, что символ новой строки становится токеном другого типа. Итак, давайте предположим, что у вас есть слова, разделенные «пробелами» в качестве токенов и символ новой строки в качестве собственного токена.
Затем вы можете создать тип токена.
Тогда все, что вам нужно сделать, это написать операторы потока для токена:
#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";
}
}
Другие советы
Я не знаю, почему вы считаете std :: getline
плохим. Вы все еще можете распознавать переводы строк.
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;
}
}
Это еще один крутой и гораздо менее многословный способ, с которым я наткнулся на токенизацию строк.
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);
}