Reading input using .putback()

Oct 21, 2008 at 10:58pm
Hey all, I'm having a "wtf" moment... Perhaps someone could assist.

In this program, the user inputs commands to perform basic arithmetic operations in English (ie: multiply 5 and 2) and the result is output to the console (5 * 2 = 10). Now, I'm able to get the operation and the first numeric value just fine. However, getting the other number has proven... a challenge. I have tried many different iterations of this code and still no success. I'm pretty certain it has to do with the structure of my while loop or the manner in which I'm using the .putback method, but not being especially familiar with either, I'm uncertain as to how to proceed.

Now, I throw myself upon the mercy of the general forum... Can anyone tell me what I'm doing wrong with this program and how to fix it?

_____________________________________________________________________


#include <iostream.h>


void main ()
{
double x, y;
const int size = 20;
char operation[size];
char c;
char oper;

cout << "Please enter, in English, the arithmetic operation you wish to perform. \n\n";
cin >> operation;
cin >> x;

oper = operation[0];

c = cin.get();

while ( ! ((c >= '0') || (c <= '9') || c == '.' || c== '-'))
cin.putback(c);

cin.putback(c);
cin >> y;


switch (oper)
{
case 'm': cout << "\n" << x << " * " << y << " = " << x*y << "\n\n";
break;
case 'M': cout << "\n" << x << " * " << y << " = " << x*y << "\n\n";
break;
case 'a': cout << "\n" << x << " + " << y << " = " << x+y << "\n\n";
break;
case 'A': cout << "\n" << x << " + " << y << " = " << x+y << "\n\n";
break;
case 's': cout << "\n" << x << " - " << y << " = " << x-y << "\n\n";
break;
case 'S': cout << "\n" << x << " - " << y << " = " << x-y << "\n\n";
break;

}



cin.ignore();
cin.ignore();

}
Last edited on Oct 21, 2008 at 11:08pm
Oct 21, 2008 at 11:27pm
cin >> operation; Won't work. The >> operator will stop the on the first space and ignore the rest.

Use cin.getline(operation, size);.

Oct 21, 2008 at 11:54pm
But that part does work...
cin>> operation; // gets the operation and stores it.
cin>> x; // gets the value for x and stores it.
it's the rest of the data that I'm not able to get (ignoring whatever is between the x value and the y value).

For example, if I remove the while loop and the .putback statements, it'll get the operation, and the value for x. If you assign a value to y (say, 5), it'll run for any of the cases shown.
Last edited on Oct 22, 2008 at 12:27am
Oct 22, 2008 at 12:55am
http://www.cplusplus.com/reference/iostream/istream/putback.html

I don't know why you are using putback at all. It seems pointless to me.
Last edited on Oct 22, 2008 at 12:55am
Oct 22, 2008 at 12:59am
I thought I did, but then I realized I had the idea a little reversed...

instead of this section right here:

c = cin.get();

while ( ! ((c >= '0') || (c <= '9') || c == '.' || c== '-'))
cin.putback(c);

cin.putback(c);
cin >> y;


I am now using
c = cin.get();

while ( ! ((c >= '0') && (c <= '9') || c == '.' || c == '-') )
cin.get(c);

cin.putback(c);
cin >> y;


I don't really know what I was thinking with the first one, but now I see what the issue was. It just kept putting values back and never really reading them. With the fix, it reads each character that's neither a negative, decimal point, nor number and basically ignores it. When it gets to a character that satisfies the condition for the loop, it stops, puts it back into the stream, and then reads it into the double.

For future reference as an alternate solution, would you be so kind as to show me what you would do to get the command, and both the x and y values?
Last edited on Oct 22, 2008 at 1:03am
Oct 22, 2008 at 1:20am
Here is a Quick and dirty way to do it. It looks for spaces as the seperator, but you could look for other things.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>

using namespace std;


int main() {

  cout << "Please input equation (e.g 3 + 5):";

  char cEquation[128] = {0};
  cin.getline(cEquation, 128);

  string sEquation = string(cEquation);

  cout << "Your equation was: " << sEquation << endl;

  int iSpace        = sEquation.find(" ");
  int iSecondSpace  = sEquation.find(" ", iSpace+1);

  int iFirstNumber = atoi(sEquation.substr(0, iSpace).c_str());
  cout << "First Number was: " << iFirstNumber << endl;

  string sOperator = sEquation.substr(iSpace+1, iSecondSpace - (iSpace+1));
  cout << "Operator was: " << sOperator << endl;

  int iSecondNumber = atoi(sEquation.substr(iSecondSpace+1, sEquation.length()).c_str());
  cout << "Second Number was: " << iSecondNumber << endl;

  cout << "Equation: " << iFirstNumber << sOperator << iSecondNumber << endl;

  return 0;
}
Oct 22, 2008 at 1:44am
While I thoroughly appreciate your efforts and thank you wholeheartedly, that's not what I'm looking for at all. I would love to be able to use something like that, but it doesn't do what my program is required to do. :(
Oct 22, 2008 at 7:05pm
It's not suppose to be an answer for you. Merely an illustration of a way to read in a string and split it in memory without having to play around with the IOStream. It's also easier for me to split that functionality off into another function now, as I am not reliant on Cin being the source of data.
Topic archived. No new replies allowed.