#include #include #include #include "fraction.h" const int LINE_LENGTH = 81; Fraction current_value; bool eat( istream& is ) { char ch; while( is.get( ch ) ) { if( ch == '\n' ) { is.putback( ch ); return false; } else if( !isspace( ch ) ) { is.putback( ch ); return true; } } return false; } bool getNumber( istream& is, myInt& num ) { if( !eat( is ) ) { return false; } num = myInt( 0 ); char ch; if( !isdigit( is.peek() ) ) { return false; } while( is.get( ch ) ) { if( isdigit( ch ) ) { num = myInt( 10 ) * num + myInt( (ch - '0') ); } else { is.putback( ch ); break; } } return true; } bool getFraction( istream& is, Fraction& frac ) { myInt num( 0 ); myInt denom( 0 ); if( !getNumber( is, num ) ) { return false; } if( !eat( is ) ) { // Nothing left on line. That's okay - return a single int. frac = Fraction( num ); return true; } char ch; is.get( ch ); if( ch != '/' ) { return false; } if( !getNumber( is, denom ) ) { return false; } frac = Fraction( num, denom ); return true; } void ignoreLine( istream& is ) { cout << "incomprehensible line ignored" << endl; char ch; while( cin.get( ch ) && ch != '\n' ); } bool readArgument( istream& is, Fraction& frac ) { if( getFraction( is, frac ) ) { if( eat( cin ) ) { ignoreLine( cin ); } else { return true; } } else { ignoreLine( cin ); } return false; } int main() { char ch; Fraction arg; cout << "Current value is " << current_value << endl; while( true ) { while( !eat( cin ) ) { if( cin ) { cin.get(); } else { return 0; } } cin.get( ch ); switch( ch ) { case '+': if( readArgument( cin, arg ) ) { current_value = current_value + arg; } break; case '-': if( eat( cin ) ) { if( getFraction( cin, arg ) ) { if( eat( cin ) ) { ignoreLine( cin ); } else { current_value = current_value - arg; } } else { ignoreLine( cin ); } } else { current_value = -current_value; cin.get(); } break; case '*': if( readArgument( cin, arg ) ) { current_value = current_value * arg; } break; case '/': if( readArgument( cin, arg ) ) { current_value = current_value / arg; } break; case 'd': if( eat( cin ) ) { ignoreLine( cin ); } else { cout << current_value.toDouble() << endl; } break; case 'e': if( eat( cin ) ) { ignoreLine( cin ); } else { char buf[ LINE_LENGTH ]; current_value.expand( buf, LINE_LENGTH ); cout << buf << endl; } break; default: if( isdigit( ch ) ) { cin.putback( ch ); if( readArgument( cin, arg ) ) { current_value = arg; } } else { ignoreLine( cin ); } break; } cout << "Current value is " << current_value << endl; } }