https://rentry.org/PPP2_p400

// Code derived from Stroustrup's PPP2 book
// § 11.7 Using nonstandard separators
//  -and beginning on p 400

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

//------------------------------------------------------------------------------

// like an istream, but the user can add to the set of whitespace characters
class Punct_stream {
 public:
  Punct_stream(istream& is) : source{is}, sensitive{true} {}

  void whitespace(string const& s) { white = s; }  // make s the whitespace set
  void add_white(char c) { white += c; }           // add to the whitespace set
  bool is_whitespace(char c);  // is c in the whitespace set?

  void case_sensitive(bool b) { sensitive = b; }
  bool is_case_sensitive() { return sensitive; }

  Punct_stream& operator>>(string& s);

  operator bool();

 private:
  istream&      source;     // character source
  istringstream buffer;     // we let buffer do our formatting
  string        white;      // characters considered “whitespace”
  bool          sensitive;  // is the stream case-sensitive?
};

Punct_stream& Punct_stream::operator>>(string& s)
{
  while (! (buffer >> s)) {  // try to read from buffer (skip normal whitespace)
    if (buffer.bad() || ! source.good())
      return *this;

    buffer.clear();

    // replenish buffer from source:

    string line;
    getline(source, line);  // get a line from source stream

    // do character replacement as needed on that line:
    for (char& ch : line)
      if (is_whitespace(ch))
        ch = ' ';  // to space
      else if (! sensitive)
        ch = tolower(ch);  // to lower case

    buffer.str(line);  // put that now-processed line into buffer's stream
  }

  return *this;  // (see §17.10)
}

bool Punct_stream::is_whitespace(char c)
{
  for (char w : white)
    if (c == w)
      return true;

  return false;
}

// "A member function called operator bool() defines a conversion to bool." p404
Punct_stream::operator bool()
{
  return (! (source.fail() || source.bad()) && source.good());
}

//------------------------------------------------------------------------------

// given text input, produce a sorted list of all words in that text
// ignore punctuation and case differences
// eliminate duplicates from the output
int main()
{
  // example input:
  /*

  There are only two kinds of languages: languages that people complain
  about, and languages that people don't use.

  */
  cout << "please enter words (ctrl+d to end input)\n";

  Punct_stream ps{cin};
  ps.whitespace(";:,.?!()\"{}<>/&$@#%^*|~");  // note \“ means ” in string
  ps.case_sensitive(false);

  vector<string> vs;
  for (string word; ps >> word;)  // read words
    vs.push_back(word);           //

  sort(begin(vs), end(vs));  // sort in lexicographical order

  for (int i = 0; i < (int)vs.size(); ++i)  // print out dictionary
    if (i == 0 || vs[i] != vs[i - 1])       //
      cout << vs[i] << '\n';
}

build & run:

g++ -std=c++20 -O2 -Wall -pedantic ./ch_11/main_p400.cpp && ./a.out

PrevUp

Edit
Pub: 09 Apr 2023 06:11 UTC
Edit: 08 May 2023 12:18 UTC
Views: 659