I am trying to convert this C program to Java.
double expression();
char token() {
char ch;
std::cin >> ch;
return ch;
}
double factor() {
double val = 0;
char ch = token();
if (ch == '(') {
val = expression();
ch = token();
if (ch != ')') {
std::string error = std::string("Expected ')', got: ") ch;
throw std::runtime_error(error.c_str());
}
}
else if (isdigit(ch)) {
std::cin.unget();
std::cin >> val;
}
else throw std::runtime_error("Unexpected character");
return val;
}
double term() {
int ch;
double val = factor();
ch = token();
if (ch == '*' || ch == '/') {
double b = term();
if (ch == '*')
val *= b;
else
val /= b;
}
else std::cin.unget(); // here it is
return val;
}
double expression() {
double val = term();
char ch = token();
if (ch == '-' || ch==' ') {
double b = expression();
if (ch == ' ')
val = b;
else
val -= b;
}
else std::cin.unget();
return val;
}
The program can evaluate (or simplify) mathematical expressions (i.e. (5 6-(6*2)/3) ) In term(), "unget" the character if the character is equivalent to any digit. But I can't find "unget()" in Java. And I am a little bit confused regarding this "Unget" operation.
What can I replace with the equivalent of "unget()" in C for Java?
CodePudding user response:
InputStream
interface in Java supports two methods mark
and reset
, subclasses may or may not support them.
if (!stream.markSupported())
stream = new BufferedInputStream(stream); // Supports mark/reset
// If a C function calls unget(), call mark() before token()
// in a Java function, or let token() call mark(),
// and call reset() instead of unget().
stream.mark(); // Remember current position in stream
// read data, process data
stream.reset(); // Rewind to the remembered position
CodePudding user response:
I suggest to use the scanner class to read from console. It can check if for example the next chars on the console are a int, or a given pattern (the math expression) and if so it loads the input.
For example:
// Using Scanner for Getting Input from User
String mathematicalOperation = "\([0123456789 -]*\)" ;
Pattern pattern = Pattern.compile(mathematicalOperation);
Scanner in = new Scanner(System.in);
if(in.hasNextInt){
val = in.nextInt();}
else if (in.hasNext(Pattern pattern) ) {
String expresionRaw = in.next(Pattern pattern);
val = expreion(expresionRaw);
}
Or this : if unget moves the input pointer back then if you are using in java this can be done with the reset() methid of the BufferedReader class