Leigh Omar Alpha Ответов: 1

Как создать 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, так что это не будет изменением.