c++ - 伪istream指针返回

标签 c++ pointers iostream istream

我一直在阅读 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 from buffer. 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/

相关文章:

c - 在 C 中,是否允许将某种类型的指针直接转换为另一种类型的指针?

c - 为什么我的链表头指向头前的2项

c++ - iostream,一些问题

c++ - 检查是否已从 std::istream 成功读取所有值

c++ - 为什么循环条件(即 `while (!stream.eof())` )内的 iostream::eof 被认为是错误的?

c++ - 运算符重载 ("<<") :why the “cout” did not work properly?

c++ - 将数据的某些部分从 const char * 数组复制到另一个 const char * 数组

c++ - 在 C++ 中显示错误的函数重载示例

c++ - 并排配置不正确

c++ - 将成员函数指针传递给父类