CSE 109 Test 2   Monday  14 November 2011
======================SUGGESTED ANSWERS=========================
1. Consider the ADT for a "FlipFlop," an object that is in one of two
states. Everytime it is told to "flip" it changes to the alternative state.
Write a template for a class FlipFlop. You need only implement those
constructors, methods, and functions that enable the code below to
compile.
   FlipFlop<int> a(2, 3); // A flipflop with "states" 2 and 3, initial
                      //value 2
   FlipFlop<double> c(1.7, 2.3);
   cout<<a<<c<<endl;  //OUTPUT: FF(2)FF(1.7)
   c.flip();
   cout<<c<<endl; //OUTPUT: FF(2.3)
=====================================================================
#include <iostream.h>
template <class X>
class FlipFlop{
  private:
   X state[2];
   int p;
  public:
   FlipFlop(const X &a, const X &b);
   void flip();
   template <class Y>
   friend ostream&operator<<(ostream&out,const FlipFlop<Y>&f);
};

template <class X>
FlipFlop<X>::FlipFlop(const X&a, const X&b){
  state[0]=a;
  state[1]=b;
  p=0;
}  

template <class X>
void FlipFlop<X>::flip(){
  p=1-p;
}

template <class X>
ostream&operator<<(ostream&out,const FlipFlop<X>&f){
  return out<<"FF("<<f.state[f.p]<<")";
 }
=====================================================================
2. Write a program that counts the number of characters in a file. If
the compiled program is stored in a.out, the call
   a.out aprog
either crashes because the file does not exist or prints the message
  The file 'aprog' has 207 characters
where the file 'aprog' does indeed have 207 characters.
=====================================================================
#include <iostream.h>
#include <fstream.h>
 void check(bool b,const char *mess);
 int main(int ct,char**arg){
 check(ct==2,"Must have two args on command line");
 ifstream f(arg[1]);
 check(f.good(),"Failure to open input file");
 char ch;
 int n;
 n=0;
 f.get(ch);
 while(f.good()){
     n++;
     f.get(ch);
 }
 cout<<"The file '"<<arg[1]<<"' has "<<n<<" characters\n";
}
void check(bool b,const char *mess){
  if(!b){
     cerr<<"ERROR: "<<mess<<endl;
	 exit(1);
   }
}
=====================================================================
3. Write functions that check whether a line of text satisfies the syntax
of s, given by the following diagrams, where [] indicates rectangles and
() indicates literals.  The original call to s() is shown below.

      s          +--(+)->[b]-->(-)--+
      ---------->|                  |-->[b]-->
                 +--(*)->[b]-->(/)--+
      b
      ---------->[digit]------------------------------>
                            ^                   |
                            |                   |
                            +-----[s]<---(=)<---+
      [digit] indicates a single digit
int main(){
  char ch;
  cin.get(ch);
  s(ch);
  if(ch!='\n')
   cout<<"not a ";
  cout<<"successful parse\n";
}
=====================================================================
#include <iostream>
using namespace std;

void check(bool b,const char *mess){
  if(!b){
    cerr<<"ERROR: "<<mess<<endl;
    exit(1);
  }
}
void expect(char p,char &ch,const char *mess){
  check(ch==p,mess);
  cin.get(ch);
}

void b(char &ch);
void s(char &ch){
  switch(ch){
  case '+':
    cin.get(ch);
    b(ch);
    expect('-',ch,"'-' expected");
    break;
 case '*':
   cin.get(ch);
   b(ch);
   expect('/',ch,"'*' expected");
   break;
  default:
    check(false," '+' or '-' expected");
  }
  b(ch);
}

void b(char &ch){
  expect('<',ch," '<' expected");
  while(ch=='='){
    cin.get(ch);
    s(ch);
  }
}
=====================================================================
4. Suppose you are trying to read one of the symbols +, -, +=, -=, ++, or
 --. Write a function s() that reads from an input stream and returns
 1 for ++, 2 for +=, 3 for +, 4 for --, 5 for -=, 6 for -, and 7 for
 anything else (junk). The code below shows how the function is used.
 Do note that in the code below, after the call to s() ch has the first
 character that follows the symbol(s) read. In the code below, cin is the
 input stream.
 int main(){
   char ch;
   cin.get(ch);
   cout<<s(cin,ch);
   cout<<s(cin,ch);
 }
=====================================================================
int s(istream&in,char &ch){
  switch(ch){
  case '+':
    in.get(ch);
    switch(ch){
    case '+': in.get(ch); return 1;
    case '=': in.get(ch); return 2;
    default: return 3;
    }
  case '-':
    in.get(ch);
    switch(ch){
    case '-': in.get(ch); return 4;
    case '=': in.get(ch); return 5;
    default: return 6;
    }
  default: return 7;
  }
}
=====================================================================
