我一直在阅读 Stroustrup 的编程和原理来自学 c++11。
在第 11 章中,他描述了一个从输入流中删除(变成空白)任何不需要的字符的程序。因此,例如,我可以设置一个字符串来保存字符“!”和 '。'。然后我可以输入
狗! food
并接收输出 dog food
。
但是,我不明白 main 中的字符串,word
int main ()
{
Punct_stream ps {cin};
ps.whitespace(";:,.?!()\"{}<>/&$@#%^*|~");
ps.case_sensitive(false);
cout<<"Please input words."<<"\n";
vector<string> vs;
for (string word; ps>>word;)// how does word get assigned a string? {
vs.push_back(word);
}
sort(vs.begin(), vs.end());
for (int i = 0; i<vs.size(); ++i) {
if (i==0 || vs[i]!=vs[i-1]) cout<<vs[i]<<"\n";
}
}
通过>>的重载定义赋值。
Punct_stream& Punct_stream::operator>>(string& s)
{
while (!(buffer>>s)) {
if (buffer.bad() || !source.good()) return *this;
buffer.clear();
string line;
getline(source,line); // get a line from source
for (char& ch : line)
if (is_whitespace(ch))
ch = ' ';
else if (!sensitive)
ch = tolower(ch);
buffer.str(line); //how does word become this value?
}
return *this;
}
显然,指针 this
将是 >> 的结果,但我不明白该结果如何包括将 word 分配给 istringstream buffer
的字符串。我只知道指针的基础知识,所以也许这是我的问题?
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
using namespace std;
class Punct_stream {
public:
Punct_stream(istream& is)
: source{is}, sensitive{true} { }
void whitespace(const string& s) { white = s; }
void add_white(char c) { white += c; }
bool is_whitespace(char c);
void case_sensitive(bool b) { sensitive = b; }
bool is_case_sensitive() { return sensitive; }
Punct_stream& operator>>(string& s);
operator bool();
private:
istream& source;
istringstream buffer;
string white;
bool sensitive;
};
Punct_stream& Punct_stream::operator>>(string& s)
{
while (!(buffer>>s)) {
if (buffer.bad() || !source.good()) return *this;
buffer.clear();
string line;
getline(source,line); // get a line from source
for (char& ch : line)
if (is_whitespace(ch))
ch = ' ';
else if (!sensitive)
ch = tolower(ch);
buffer.str(line); //how does word become this value?
}
return *this;
}
Punct_stream::operator bool()
{
return !(source.fail() || source.bad()) && source.good(); }
bool Punct_stream::is_whitespace(char c) {
for (char w : white)
if (c==w) return true; return false;
}
int main ()
{
Punct_stream ps {cin};
ps.whitespace(";:,.?!()\"{}<>/&$@#%^*|~");
ps.case_sensitive(false);
cout<<"Please input words."<<"\n";
vector<string> vs;
for (string word; ps>>word;)// how does word get assigned a string? {
vs.push_back(word);
}
sort(vs.begin(), vs.end());
for (int i = 0; i<vs.size(); ++i) {
if (i==0 || vs[i]!=vs[i-1]) cout<<vs[i]<<"\n";
}
}
最佳答案
诀窍在于 operator >>
中的 while
循环与从流读取时通常执行的逻辑相反。通常,您会做这样的事情(事实上 main
会做):
while (stream >> aString)
但是请注意,提取器中的 while
有一个否定:
Try extracting
s
frombuffer
. If you fail, do one iteration of the loop and try again.
开始时,buffer
是空的,因此提取s
将失败并进入循环体。循环体所做的是从 source
(被包装的流)中读取一行,将该行的选定字符转换为空白,将此行设置为 buffer< 的内容
(通过 buffer.str(line);
调用)。
因此,行转换后,它被排队到 buffer
中。然后循环的下一次迭代来了,它再次尝试从 buffer
中提取 s
。如果该行有任何非空白,第一个单词将被提取(其余的将保留在 buffer
中以供进一步阅读)。如果该行只有空格,则再次进入循环体。
一旦成功提取s
,循环终止,函数退出。
在下一次调用时,它将使用 buffer
中剩余的内容,根据需要从 source
重新填充缓冲区(通过我在上面解释的过程)。
关于c++ - 伪istream指针返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35601010/