Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 伪istream指针返回_C++_Pointers_Iostream_Istream - Fatal编程技术网

C++ 伪istream指针返回

C++ 伪istream指针返回,c++,pointers,iostream,istream,C++,Pointers,Iostream,Istream,我一直在学习Stroustrup的编程和原理来自学c++11。 在第11章中,他描述了一个从输入流中删除(变成空白)任何不需要的字符的程序。例如,我可以设置一个字符串来保存字符“!”及"。然后我就可以输入了 狗!食物并接收输出狗粮 但是,我不明白字符串,word在main中是如何工作的 int main () { Punct_stream ps {cin}; ps.whitespace(";:,.?!()\"{}<>/&$@#%^*|~");

我一直在学习Stroustrup的编程和原理来自学c++11。 在第11章中,他描述了一个从输入流中删除(变成空白)任何不需要的字符的程序。例如,我可以设置一个字符串来保存字符“!”及"。然后我就可以输入了
狗!食物
并接收输出狗粮

但是,我不明白字符串,
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)