From: brm30@diag.amdahl.com (Brian Moyle)
Newsgroups: comp.lang.c++
Subject: "cin" help requested
Keywords: cin input problem
Date: 15 Sep 92 21:47:13 GMT
Organization: Amdahl Corporation, Cupertino, CA

Hello,

   I'm fairly new to C++ programming, but I've run into a little 
problem that seems to qualify as a bug (or ignorance on my part).  The 
following program was taken from The Waite Group's, "C++ Programming," 
book, by John Berry, copyright 1988 (fourth printing -- 1990).  On page 
44, the following paragraph provides an explanation of how the 'while' 
loop exits:

"The program also uses a trick to develop an easy user interface.  
Recall that a character is actually an integer value.  Because implicit 
type conversion is easy and unregulated in C++, the program can accept 
as input the value 'exit.'  The 'e' is converted from its integer 
representation into a real number.  The same thing happens to the 'i'.  
However, the value 'x' is stored in the character variable 'opr'.  This 
value then triggers the exit clause of the 'switch'."

   When I run this program, and type "exit" to terminate the loop, the 
program seems to ignore any future attempts at input via the "cin" 
routine.  Am I violating some rule in C++ which I don't yet understand?

   To the best of my knowledge, I am running gcc 2.2.2 on a Sun 
SPARCstation IPC.  Here are the results of compiling with the "-v" 
option:

~/c++_prog > gcc -v calc.C -lg++
Reading specs from /usr/local/pswd/lib/gcc-lib/sun4/2.2.2/specs
gcc version 2.2.2
 /usr/local/pswd/lib/gcc-lib/sun4/2.2.2/cpp -lang-c++ -v -undef
 -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -Dsparc -Dsun -Dunix
 -D__sparc__ -D__sun__ -D__unix__ -D__sparc -D__sun -D__unix calc.C
 /usr/tmp/cca13438.i
GNU CPP version 2.2.2 (sparc)
 /usr/local/pswd/lib/gcc-lib/sun4/2.2.2/cc1plus /usr/tmp/cca13438.i
 -quiet -dumpbase calc.cc -version -o /usr/tmp/cca13438.s
GNU C++ version 2.2.2 (sparc) compiled by GNU C version 2.2.2.
 as -o calc.o /usr/tmp/cca13438.s
 /usr/local/pswd/lib/gcc-lib/sun4/2.2.2/ld -e start -dc -dp
 /lib/crt0.o -L/usr/local/pswd/lib/gcc-lib/sun4/2.2.2
 -L/usr/local/pswd/lib calc.o -lg++ -lgcc -lc -lgcc

Also, this might be useful:

~/c++_prog > uname -a
   SunOS bmoyle 4.1.1 1 sun4c


Hopefully, this is enough information.  Please send any
recommendations to this newsgroup or:

          brm30@diag.amdahl.com

Thanks, in advance, for any help!

Brian Moyle
(408)992-3185
brm30@diag.amdahl.com


*********************************************************************


program input/output:
----------------------------------------------------------------------
enter expression 5+3
x=5  y=3  opr=+
=8

enter expression 8*2
x=8  y=2  opr=*
=16

enter expression exit
x=8  y=2  opr=*
=16

enter expression x=8  y=2  opr=*
=16

enter expression x=8  y=2  opr=*
=16

enter expression x=8  y=2  opr=*
=16

enter expression x=8  y=2  opr=*
=16

               .
               .      (continues until terminated)
               .

----------------------------------------------------------------------



program listing: calc.C
----------------------------------------------------------------------
#include <stream.h>

// define some useful substitutions

#define BLANK ' '
#define STOP 0

main ()
{
   double x,y,
          radd(double, double), // declare a simple add function,
          rsub(double, double), // ... a subtraction function,
          rmul(double, double), // ... multiplication, ...
          rdiv(double, double); // ... and finally, a division function.
   char opr = BLANK;      // declare a variable for the operator

   while (opr != STOP)  {       // continue until the user says "exit"
      cout << "enter expression ";   // prompt...
      cin >> x >> opr >> y;          // ... read ...

      // I added this line for "debugging"
      cout << "x=" << x << "  y=" << y << "  opr=" << opr << endl;

      switch (opr)  {      // ... and evaluate
         case '+' : cout << "=" << radd(x,y);   // create a clause for each
                    break;                      // operation
         case '-' : cout << "=" << rsub(x,y);
                    break;
         case '*' : cout << "=" << rmul(x,y);
                    break;
         case '/' : cout << "=" << rdiv(x,y);
                    break;
         case 'x' : opr = STOP;      //... a cheap trick, "x" is the
                    break;           // second letter in "exit"
         default  : cout << "not yet implemented!\n"; // unbounded optimism
         }  // switch

      cout << "\n\n";

   }  // while
}  // main()

//////////////////////////////////////////////////////////////////////

double radd(double a, double b)   // a function to add doubles
{
   return(a+b);
}

//////////////////////////////////////////////////////////////////////

double rsub(double a, double b)   // ... one to subtract them
{
   return(a-b);
}

//////////////////////////////////////////////////////////////////////

double rmul(double a, double b)   // ... multiply ...
{
   return(a*b);
}

//////////////////////////////////////////////////////////////////////

double rdiv(double a, double b)   // ... and divide
{
   if (b == 0)   // don't forget to check for division by zero.
      return 0;
   return(a/b);
}

//////////////////////////////////////////////////////////////////////

----------------------------------------------------------------------
Newsgroups: comp.lang.c++