C++ 伪istream指针返回
我一直在学习Stroustrup的编程和原理来自学c++11。 在第11章中,他描述了一个从输入流中删除(变成空白)任何不需要的字符的程序。例如,我可以设置一个字符串来保存字符“!”及"。然后我就可以输入了C++ 伪istream指针返回,c++,pointers,iostream,istream,C++,Pointers,Iostream,Istream,我一直在学习Stroustrup的编程和原理来自学c++11。 在第11章中,他描述了一个从输入流中删除(变成空白)任何不需要的字符的程序。例如,我可以设置一个字符串来保存字符“!”及"。然后我就可以输入了 狗!食物并接收输出狗粮 但是,我不明白字符串,word在main中是如何工作的 int main () { Punct_stream ps {cin}; ps.whitespace(";:,.?!()\"{}<>/&$@#%^*|~");
狗!食物
并接收输出狗粮
但是,我不明白字符串,word
在main中是如何工作的
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";
}
}
显然,指针这个
将是>>的结果,但我不明白这个结果如何包括分配istringstream缓冲区的字符串。我只知道指针的基本知识,所以这可能是我的问题
#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";
}
}
#包括
#包括
#包括
#包括
使用名称空间std;
类点状流{
公众:
点流(istream&is)
:source{is},sensitive{true}{}
空空白(常量字符串&s){white=s;}
void add_white(char c){white+=c;}
bool是_空格(char c);
区分大小写无效(bool b){sensitive=b;}
bool区分大小写(){返回区分;}
点流和运算符>>(字符串和s);
运算符bool();
私人:
istream&源;
istringstream缓冲区;
白色的线;
布尔敏感;
};
点流和点流::运算符>>(字符串和s)
{
而(!(缓冲>>s)){
if(buffer.bad()| |!source.good())返回*this;
buffer.clear();
弦线;
getline(源,行);//从源获取一行
用于(字符和通道:行)
if(是_空格(ch))
ch='';
否则,如果(!敏感)
ch=托洛尔(ch);
str(line);//word是如何变成这个值的?
}
归还*这个;
}
点流::运算符bool()
{
return!(source.fail()| | source.bad())&&source.good()}
布尔点_流::is_空格(字符c){
用于(字符w:白色)
如果(c==w),则返回true;返回false;
}
int main()
{
点状流ps{cin};
ps.whitespace(“;:,.?!()\”{}/&$@#%^*| ~”;
ps.区分大小写(错误);
cout诀窍在于操作符>
中的while
循环与从流中读取时通常执行的操作逻辑相反。通常,您会执行类似的操作(实际上,main
执行此操作):
但是,请注意,提取器中的while
有一个否定:
尝试从缓冲区中提取s
。如果失败,请重复循环一次,然后重试
在开始时,buffer
为空,因此提取s
将失败,循环体将被输入。循环体所做的是从source
(正在包装的流)读取一行,将该行的选定字符转换为空白,并将该行设置为buffer
(通过buffer.str)的内容(行);
call)
因此,在转换行之后,它将排队进入buffer
。然后循环的下一次迭代开始,它再次尝试从buffer
中提取s
。如果该行有任何非空白,将提取第一个字(其余字将保留在buffer
中以备进一步读取)。如果该行只有空格,则再次输入循环体
成功提取s
后,循环终止,函数退出
在下一次调用中,它将处理缓冲区中剩余的内容,根据需要从源
重新填充缓冲区(通过我上面解释的过程).该值被分配给您的out参数s
,在操作符>
中的语句缓冲区>>s
,返回*这;
已经完成,因为作者希望允许读取链接,例如:ps>>word1>>word2>>word3
。如果不返回,您将被迫对每一条语句使用一次读取回答另一个OP问题:返回*这个
意味着什么。哈哈,谢谢。我一直在试图弄清楚这是怎么回事,当我试图通读代码时,我没有对while循环给予足够的注意。
#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";
}
}
while (stream >> aString)