C++ 读取文件令牌
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/275355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ Reading file Tokens
提问by BobS
another request sorry.. Right now I am reading the tokens in one by one and it works, but I want to know when there is a new line..
另一个请求抱歉..现在我正在一个一个地读取令牌并且它有效,但我想知道什么时候有新行..
if my file contains
如果我的文件包含
Hey Bob
Now
should give me
应该给我
Hey
Bob
[NEW LINE]
NOW
Is there a way to do this without using getline?
有没有办法在不使用 getline 的情况下做到这一点?
回答by Martin York
Yes the operator>> when used with string read 'white space' separated words. A 'White space' includes space tab and new line characters.
是的 operator>> 与字符串一起使用时读取“空白”分隔的单词。“空白”包括空格制表符和换行符。
If you want to read a line at a time use std::getline()
The line can then be tokenized separately with a string stream.
如果您想一次读取一行,请使用 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";
}
Small addition:
小补充:
Without using getline()
不使用 getline()
So you really want to be able to detect a newline. This means that newline becomes another type of token. So lets assume that you have words separated by 'white spaces' as tokens and newline as its own token.
所以你真的希望能够检测到换行符。这意味着换行符成为另一种类型的标记。因此,让我们假设您将用“空格”分隔的单词作为标记,将换行符作为自己的标记。
Then you can create a Token type.
Then all you have to do is write the stream operators for a token:
然后你可以创建一个 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";
}
}
回答by Johannes Schaub - litb
I don't know why you think std::getline
is bad. You can still recognize newlines.
我不知道你为什么认为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;
}
}
回答by the_drow
This is another cool and much less verbose way I came across to tokenize strings.
这是我遇到的另一种很酷且不那么冗长的标记字符串的方法。
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);
}