Как создать clculator, который считывает входной файл, содержащий выражение, вычисляет его и отправляет out put в выходной файл на языке C++
1.калькулятор должен иметь входной текстовый файл, в котором выполняется весь пользовательский ввод
2. он должен иметь выходной текстовый файл, в который будет отправлен весь результат.
3. он должен уметь вычислять BOD MAS EXPRESSION,SIN,COS и представлять ответ в десятичном виде независимо от того,имеет ли выражение целое число, шестнадцатеричное и т. д
4. ЭТО ДОЛЖНО БЫТЬ КОНСОЛЬНОЕ ПРИЛОЖЕНИЕ. он должен быть закодирован на языке C++
Что я уже пробовал:
#include "calculator.hpp" #include <iostream> #include <iomanip> #include <string> #define STR1(s) #s #define TOSTRING(s) STR1(s) /// Test expressions #define EXPR1 45345 + 0 + 0xdf234 - 1000 % 7 #define EXPR2 (0 + 0xdf234 - 1000) * 3 / 2 % 999 #define EXPR3 1 << 16 #define EXPR4 (0 + ~(0xdf234 & 1000) * 3) / -2 #define EXPR5 ((1 << 16) + (1 << 16)) >> 0X5 #define EXPR6 1+(((2+(3+(4+(5+6)* -7)/8))&127)<<1) *-3 #define EXPR7 100000000 + (1 << 16) + (1 << 16) #define EXPR8 1-~1 #define EXPR9 1- ~1*0xfFa/( ((((8+(6|(4 *(2*(1)*3)*5)|7)+9))))) #define EXPRa ((12|13)<<8)>>((1|127) %10&(31+7)) #define EXPRb ((((((((((5)))))) ))))- ((((((((( 6))))))))) int failed = 0; void compare(int result, const std::string& str) { int r = calculator::eval(str); std::cout << (r == result ? "Correct: " : "Error: "); std::cout << std::setw(50) << str << " = " << std::setw(10) << r; if (r != result) { std::cout << " != " << result; failed++; } std::cout << std::endl; } int main() { std::cout.setf(std::ios::left); compare(EXPR1, TOSTRING(EXPR1)); compare(EXPR2, TOSTRING(EXPR2)); compare(EXPR3, TOSTRING(EXPR3)); compare(EXPR4, TOSTRING(EXPR4)); compare(EXPR5, TOSTRING(EXPR5)); compare(EXPR6, TOSTRING(EXPR6)); compare(EXPR7, TOSTRING(EXPR7)); compare(EXPR8, TOSTRING(EXPR8)); compare(EXPR9, TOSTRING(EXPR9)); compare(EXPRa, TOSTRING(EXPRa)); compare(EXPRb, TOSTRING(EXPRb)); if (failed != 0) { std::cerr << failed << " test(s) failed!" << std::endl; return 1; } std::cout << "All tests passed successfully!" << std::endl; return 0; }
я пробовал это , что хорошо работает , но моя проблема заключается в том, что я не хочу определять выражение в этом коде, они должны быть во входном текстовом файле, и код должен быть в состоянии прочитать все строки в файле, вычислить их и дать выходу выходной текстовый файл.
[редактировать]
Получил следующее по прямой электронной почте. Пожалуйста, не отправляйте сообщения частным лицам, а публикуйте обновления здесь, в вашем вопросе.
main c++ #include <calculator.hpp> int main() { while file.hasLine() { line = file.getLine() int result = calculator::eval(line); outputFile.write(line); } } 2. calculator.hpp #ifndef CALCULATOR_HPP #define CALCULATOR_HPP #include <stdexcept> #include <string> #include <sstream> #include <stack> #include <cstddef> #include <cctype> namespace calculator { /// calculator::eval() throws a calculator::error if it fails /// to evaluate the expression string. /// class error : public std::runtime_error { public: error(const std::string& expr, const std::string& message) : std::runtime_error(message), expr_(expr) { } #if __cplusplus < 201103L ~error() throw() { } #endif std::string expression() const { return expr_; } private: std::string expr_; }; template <typename T> class ExpressionParser { public: /// Evaluate an integer arithmetic expression and return its result. /// @throw error if parsing fails. /// T eval(const std::string& expr) { T result = 0; index_ = 0; expr_ = expr; try { result = parseExpr(); if (!isEnd()) unexpected(); } catch (const calculator::error&) { while(!stack_.empty()) stack_.pop(); throw; } return result; } /// Get the integer value of a character. T eval(char c) { std::string expr(1, c); return eval(expr); } private: enum { OPERATOR_NULL, OPERATOR_BITWISE_OR, /// | OPERATOR_BITWISE_XOR, /// ^ OPERATOR_BITWISE_AND, /// & OPERATOR_BITWISE_SHL, /// << OPERATOR_BITWISE_SHR, /// >> OPERATOR_ADDITION, /// + OPERATOR_SUBTRACTION, /// - OPERATOR_MULTIPLICATION, /// * OPERATOR_DIVISION, /// / OPERATOR_MODULO, /// % OPERATOR_POWER, /// ** OPERATOR_EXPONENT /// e, E }; struct Operator { /// Operator, one of the OPERATOR_* enum definitions int op; int precedence; /// 'L' = left or 'R' = right int associativity; Operator(int opr, int prec, int assoc) : op(opr), precedence(prec), associativity(assoc) { } }; struct OperatorValue { Operator op; T value; OperatorValue(const Operator& opr, T val) : op(opr), value(val) { } int getPrecedence() const { return op.precedence; } bool isNull() const { return op.op == OPERATOR_NULL; } }; /// Expression string std::string expr_; /// Current expression index, incremented whilst parsing std::size_t index_; /// The current operator and its left value /// are pushed onto the stack if the operator on /// top of the stack has lower precedence. std::stack<OperatorValue> stack_; /// Exponentiation by squaring, x^n. static T pow(T x, T n) { T res = 1; while (n > 0) { if (n % 2 != 0) { res *= x; n -= 1; } n /= 2; if (n > 0) x *= x; } return res; } T checkZero(T value) const { if (value == 0) { std::string divOperators("/%"); std::size_t division = expr_.find_last_of(divOperators, index_ - 2); std::ostringstream msg; msg << "Parser error: division by 0"; if (division != std::string::npos) msg << " (error token is \"" << expr_.substr(division, expr_.size() - division) << "\")"; throw calculator::error(expr_, msg.str()); } return value; } T calculate(T v1, T v2, const Operator& op) const { switch (op.op) { case OPERATOR_BITWISE_OR: return v1 | v2; case OPERATOR_BITWISE_XOR: return v1 ^ v2; case OPERATOR_BITWISE_AND: return v1 & v2; case OPERATOR_BITWISE_SHL: return v1 << v2; case OPERATOR_BITWISE_SHR: return v1 >> v2; case OPERATOR_ADDITION: return v1 + v2; case OPERATOR_SUBTRACTION: return v1 - v2; case OPERATOR_MULTIPLICATION: return v1 * v2; case OPERATOR_DIVISION: return v1 / checkZero(v2); case OPERATOR_MODULO: return v1 % checkZero(v2); case OPERATOR_POWER: return pow(v1, v2); case OPERATOR_EXPONENT: return v1 * pow(10, v2); default: return 0; } } bool isEnd() const { return index_ >= expr_.size(); } /// Returns the character at the current expression index or /// 0 if the end of the expression is reached. /// char getCharacter() const { if (!isEnd()) return expr_[index_]; return 0; } /// Parse str at the current expression index. /// @throw error if parsing fails. /// void expect(const std::string& str) { if (expr_.compare(index_, str.size(), str) != 0) unexpected(); index_ += str.size(); } void unexpected() const { std::ostringstream msg; msg << "Syntax error: unexpected token \"" << expr_.substr(index_, expr_.size() - index_) << "\" at index " << index_; throw calculator::error(expr_, msg.str()); } /// Eat all white space characters at the /// current expression index. /// void eatSpaces() { while (std::isspace(getCharacter()) != 0) index_++; } /// Parse a binary operator at the current expression index. /// @return Operator with precedence and associativity. /// Operator parseOp() { eatSpaces(); switch (getCharacter()) { case '|': index_++; return Operator(OPERATOR_BITWISE_OR, 4, 'L'); case '^': index_++; return Operator(OPERATOR_BITWISE_XOR, 5, 'L'); case '&': index_++; return Operator(OPERATOR_BITWISE_AND, 6, 'L'); case '<': expect("<<"); return Operator(OPERATOR_BITWISE_SHL, 9, 'L'); case '>': expect(">>"); return Operator(OPERATOR_BITWISE_SHR, 9, 'L'); case '+': index_++; return Operator(OPERATOR_ADDITION, 10, 'L'); case '-': index_++; return Operator(OPERATOR_SUBTRACTION, 10, 'L'); case '/': index_++; return Operator(OPERATOR_DIVISION, 20, 'L'); case '%': index_++; return Operator(OPERATOR_MODULO, 20, 'L'); case '*': index_++; if (getCharacter() != '*') return Operator(OPERATOR_MULTIPLICATION, 20, 'L'); index_++; return Operator(OPERATOR_POWER, 30, 'R'); case 'e': index_++; return Operator(OPERATOR_EXPONENT, 40, 'R'); case 'E': index_++; return Operator(OPERATOR_EXPONENT, 40, 'R'); default : return Operator(OPERATOR_NULL, 0, 'L'); } } static T toInteger(char c) { if (c >= '0' && c <= '9') return c -'0'; if (c >= 'a' && c <= 'f') return c -'a' + 0xa; if (c >= 'A' && c <= 'F') return c -'A' + 0xa; T noDigit = 0xf + 1; return noDigit; } T getInteger() const { return toInteger(getCharacter()); } T parseDecimal() { T value = 0; for (T d; (d = getInteger()) <= 9; index_++) value = value * 10 + d; return value; } T parseHex() { index_ = index_ + 2; T value = 0; for (T h; (h = getInteger()) <= 0xf; index_++) value = value * 0x10 + h; return value; } bool isHex() const { if (index_ + 2 < expr_.size()) { char x = expr_[index_ + 1]; char h = expr_[index_ + 2]; return (std::tolower(x) == 'x' && toInteger(h) <= 0xf); } return false; } /// Parse an integer value at the current expression index. /// The unary `+', `-' and `~' operators and opening /// parentheses `(' cause recursion. /// T parseValue() { T val = 0; eatSpaces(); switch (getCharacter()) { case '0': if (isHex()) val = parseHex(); else val = parseDecimal(); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': val = parseDecimal(); break; case '(': index_++; val = parseExpr(); eatSpaces(); if (getCharacter() != ')') { if (!isEnd()) unexpected(); throw calculator::error(expr_, "Syntax error: `)' expected at end of expression"); } index_++; break; case '~': index_++; val = ~parseValue(); break; case '+': index_++; val = parseValue(); break; case '-': index_++; val = parseValue() * static_cast<T>(-1); break; default : if (!isEnd()) unexpected(); throw calculator::error(expr_, "Syntax error: value expected at end of expression"); } return val; } /// Parse all operations of the current parenthesis /// level and the levels above, when done /// return the result (value). /// T parseExpr() { stack_.push(OperatorValue(Operator(OPERATOR_NULL, 0, 'L'), 0)); // first parse value on the left T value = parseValue(); while (!stack_.empty()) { // parse an operator (+, -, *, ...) Operator op(parseOp()); while (op.precedence < stack_.top().getPrecedence() || ( op.precedence == stack_.top().getPrecedence() && op.associativity == 'L')) { // end reached if (stack_.top().isNull()) { stack_.pop(); return value; } // do the calculation ("reduce"), producing a new value value = calculate(stack_.top().value, value, stack_.top().op); stack_.pop(); } // store on stack_ and continue parsing ("shift") stack_.push(OperatorValue(op, value)); // parse value on the right value = parseValue(); } return 0; } }; template <typename T> inline T eval(const std::string& expression) { ExpressionParser<T> parser; return parser.eval(expression); } template <typename T> inline T eval(char c) { ExpressionParser<T> parser; return parser.eval(c); } inline int eval(const std::string& expression) { return eval<int>(expression); } inline int eval(char c) { return eval<int>(c); } } // namespace calculator #endif 3. myinput file which contain the expressions that the main should read from /// Test expressions #define EXPR1 45345 + 0 + 0xdf234 - 1000 % 7 #define EXPR2 (0 + 0xdf234 - 1000) * 3 / 2 % 999 #define EXPR3 1 << 16 #define EXPR4 (0 + ~(0xdf234 & 1000) * 3) / -2 #define EXPR5 ((1 << 16) + (1 << 16)) >> 0X5 #define EXPR6 1+(((2+(3+(4+(5+6)* -7)/8))&127)<<1) *-3 #define EXPR7 100000000 + (1 << 16) + (1 << 16) #define EXPR8 1-~1 #define EXPR9 1- ~1*0xfFa/( ((((8+(6|(4 *(2*(1)*3)*5)|7)+9))))) #define EXPRa ((12|13)<<8)>>((1|127) %10&(31+7)) #define EXPRb ((((((((((5)))))) ))))- ((((((((( 6)))))))))
[/редактировать]
CHill60
Опубликуйте код, который вы используете для чтения файла и анализа строк. Также расскажите нам в чем проблема
Leigh Omar Alpha
См. раздел правка в вопросе.
Patrice T
Воспользуйся Улучшить вопрос чтобы обновить ваш вопрос.
Чтобы каждый мог обратить внимание на эту информацию.
Leigh Omar Alpha
Я хочу, чтобы код взял входной текстовый файл и прочитал все строки выражения в этом файле, оценил выражение и вывел результаты в выходной текстовый файл.
Richard MacCutchan
Используйте классы std::fstream для чтения и записи файлов: <fstream> typedefs[^].
Rick York
Для вывода вы можете просто написать в stdout, а затем перенаправить вывод с помощью '>' в любой файл, который вы хотите использовать. Вы уже пишете в stdout, так что это не будет изменением.