欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

命令行计算器

程序员文章站 2022-05-24 23:53:46
...

  在命令行下操作时,有时需要做一些计算。这时再打开图形界面的计算器比较麻烦,而Linux下的bc只能做一些简单的计算。使用C++实现命令行下计算器。

一、程序功能

  • 执行+,-,*,/,%(取两个整数相除的余数),^(乘方)运算
  • 程序可以执行的函数有
    sincostancotseccscexpasinacosatanlnloglog2log10sqrt(开二次方)abs(取绝对值)cbrt(开三次方)floorfixceilroundsum(求和)aver(求平均)min(取最小值)max(取最大值)rem(取两个整数相除的商)
  • 程序默认使用弧度制,要使用角度制,执行angle=1;取消角度制,执行angle=0
  • 定义的常数有: pi, e
  • 使用方式
    直接命令行下执行calc expression,或者输入calc进入程序后计算
  • 退出程序执行exitq

二、运行效果

命令行计算器

三、程序代码

  • main.cpp
#include "calculator.h"
#include <iostream>
#include <string>

bool set(slj::Calculator& calc, const std::string& str)
{
    if (str == "angle=0") {
        calc.set_angle(true);
        return true;
    }
    if (str == "angle=1") {
        calc.set_angle(false);
        return true;
    }
    return false;
}

int main(int argc, char* argv[])
{
    if (argc > 2) {
        std::cout << "Usage: calc or calc expression" << std::endl;
        return 0;
    }

    std::string eps;
    real result;
    slj::Calculator calc;
    if (argc == 2) {
        eps = argv[1];
        calc.set(eps);
        result = calc.calculate();
        if (calc.error(eps)) {
            std::cout << " ans \t = " << std::endl;
            std::cout << "\t\t" << result << std::endl;
            return 0;
        } else {
            std::cout << eps << std::endl;
            return 0;
        }
        return 0;
    }

    std::cout << "Command line calculator." << std::endl;
    std::cout << "Writen by Liangjin Song." << std::endl
              << std::endl;

    do {
        std::cout << "> ";
        std::cin >> eps;

        if (eps == "exit" || eps == "q") {
            break;
        }
        if (set(calc, eps)) {
            continue;
        }

        calc.set(eps);
        result = calc.calculate();
        if (calc.error(eps)) {
            std::cout << " ans \t = " << std::endl;
            std::cout << "\t\t" << result << std::endl;
        } else {
            std::cout << eps << std::endl;
        }
    } while (true);
    return 0;
}
  • calculator.h
/* the Calc class
 * writen by Liangjin Song on 20200209
*/
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include "strcase.h"
#include <string>
#include <vector>
#define stor std::stold
using real = long double;
namespace slj {
class Calculator {
private:
    enum class Symbol {
        digit,
        add, // +
        sub, // -
        mult, // *
        div, // /
        power, // ^
        mod, // %
        lbrac, // (
        rbrac, // )
        point, // .
        sin,
        cos,
        tan,
        cot,
        sec,
        csc,
        exp,
        asin,
        acos,
        atan,
        e,
        pi,
        ln,
        sqrt,
        abs,
        cbrt,
        letter,
        err,

        floor,
        fix,
        ceil,
        round,

        log10,
        log2,

        sign,

        comma,
        sum,
        aver,
        log,
        min,
        max,
        rem
    };
    enum class Error {
        unable_to_identify,
        divide_zero,
        expression_error
    };

private:
    std::string eps, eps_bak; // the expression
    std::string err; // the error information
private:
    bool cont; // is continue
    bool radian; // radian or angle, default is ragian(true)
    real to_angle(const real radn) const { return 180 * radn / pi; }
    real to_radian(const real ang) const { return ang * pi / 180; }
    int call; // the deep of the recursion function
private:
    const real pi = 3.1415926535897932384626433832795028841971693993751;
    const real e = 2.718281828459045235360287471352662497757247093699959574966967627724;

private:
    void set_err(Error err, std::string str = ""); // set the error information
    void set_err(Error err, char ch);

private:
    Symbol resolve(std::string& dig); // resolve the expression
    Symbol resolve(const char ch);
    void digit(std::string& dig);
    Symbol letter(std::string& str);
    void remove(std::string& str);

private:
    bool is_digits(std::string& str);
    bool is_integer(std::string& str);
    bool is_real(std::string& str);

private:
    void apply(Symbol sym, std::vector<real>& val, std::vector<Symbol>& sign, std::string& str, real& rs);
    void apply(std::vector<real>& val, std::vector<Symbol>& sign, real v);
    void apply_last(std::vector<real>& val, std::vector<Symbol>& sign, real& rs);
    real calcall(std::vector<real>& val, std::vector<Symbol>& sign);

public:
    Calculator(const std::string& e = "");
    ~Calculator() = default;

public:
    void set(const std::string& e);
    real calculate();
    bool error(std::string& err);
    void set_angle(bool ang = true);

private:
    bool sum, aver;
    bool log;
    bool min, max;
    bool rem;
};
}
#endif // CALCULATOR_H
  • calculator.cpp
#include "calculator.h"
#include <algorithm>
#include <cmath>

namespace slj {
Calculator::Calculator(const std::string& e)
{
    set(e);
    radian = true;
}

void Calculator::set(const std::string& e)
{
    eps_bak = eps = e;
    call = 0;
    cont = true;
    err = "";

    sum = false;
    aver = false;
    this->log = false;
    min = max = false;
    rem = false;
}

void Calculator::set_err(Error err, std::string str)
{
    switch (err) {
    case Error::unable_to_identify:
        this->err = "Unable to identify: ";
        this->err += str;
        cont = false;
        break;
    case Error::divide_zero:
        this->err = "The divisor cannot not be 0! ";
        cont = false;
        break;
    case Error::expression_error:
        this->err = "Expression error!";
        cont = false;
        break;
    default:
        this->err = "";
        break;
    }
}

void Calculator::set_err(Error err, char ch)
{
    char s1[2] = { ch, 0 };
    set_err(err, s1);
}

real Calculator::calculate()
{
    Symbol sym;
    std::string sig;
    real result = 0;

    std::vector<real> val;
    std::vector<Symbol> sign;

    do {
        sym = resolve(sig);
        if (sym == Symbol::err) {
            break;
        }
        apply(sym, val, sign, sig, result);
        if (sym == Symbol::rbrac) {
            return result;
        }
    } while (cont && eps.size());

    if (!cont) {
        return 0;
    }
    return calcall(val, sign);
}

Calculator::Symbol Calculator::resolve(std::string& sig)
{
    char ch = eps[0];
    Symbol sym = resolve(ch);

    switch (sym) {
    case Symbol::digit:
        digit(sig);
        if (!is_real(sig)) {
            cont = false;
            sym = Symbol::err;
            set_err(Error::unable_to_identify, sig);
            return sym;
        }
        break;
    case Symbol::letter:
        sym = letter(sig);
        break;
    case Symbol::add:
        sig = "+";
        break;
    case Symbol::sub:
        sig = "-";
        break;
    case Symbol::mult:
        sig = "*";
        break;
    case Symbol::div:
        sig = "/";
        break;
    case Symbol::mod:
        sig = "%";
        break;
    case Symbol::power:
        sig = "^";
        break;
    case Symbol::lbrac:
        sig = "(";
        break;
    case Symbol::rbrac:
        sig = ")";
        break;
    case Symbol::comma:
        sig = ",";
        break;
    default:
        break;
    }

    if (sym != Symbol::err) {
        remove(sig);
    }

    return sym;
}

Calculator::Symbol Calculator::resolve(const char ch)
{
    Symbol sym = Symbol::err;

    switch (ch) {
    case '(':
        sym = Symbol::lbrac;
        break;
    case ')':
        sym = Symbol::rbrac;
        break;
    case '.':
        sym = Symbol::point;
        break;
    case '+':
        sym = Symbol::add;
        break;
    case '-':
        sym = Symbol::sub;
        break;
    case '*':
        sym = Symbol::mult;
        break;
    case '/':
        sym = Symbol::div;
        break;
    case '^':
        sym = Symbol::power;
        break;
    case '%':
        sym = Symbol::mod;
        break;
    case ',':
        sym = Symbol::comma;
        break;
    default:
        break;
    }

    if (ch >= 0x30 && ch <= 0x39) {
        sym = Symbol::digit;
    }
    if (ch >= 0x61 && ch <= 0x7a) {
        sym = Symbol::letter;
    }

    if (sym == Symbol::err) {
        cont = false;
        set_err(Error::unable_to_identify, ch);
    }

    return sym;
}

void Calculator::digit(std::string& dig)
{
    char ch = 0, s[2] = { 0, 0 };
    const size_t ns = eps.size();
    dig = "";

    for (size_t i = 0; i < ns; ++i) {
        ch = eps[i];
        if (!(resolve(ch) == Symbol::digit || resolve(ch) == Symbol::point)) {
            break;
        }
        s[0] = ch;
        dig += s;
    }
}

bool Calculator::is_digits(std::string& str)
{
    return std::all_of(str.begin(), str.end(), ::isdigit);
}

bool Calculator::is_integer(std::string& str)
{
    if (str.size() <= 0) {
        return false;
    }

    if (is_digits(str)) {
        return true;
    }

    if (str.size() > 1) {
        if (str[0] == '-' || str[0] == '+') {
            std::string tstr = str.substr(1, str.size() - 1);
            return is_digits(tstr);
        }

        return false;
    }

    return false;
}

bool Calculator::is_real(std::string& str)
{
    if (is_integer(str)) {
        return true;
    }

    size_t n1 = str.find_first_of('.');
    size_t n2 = str.find_last_of('.');

    if (n1 != n2 || n1 == str.size() - 1) {
        return false;
    }

    std::string inte = str.substr(0, n1);
    std::string frac = str.substr(n1 + 1, str.size() - n1);

    return is_integer(inte) && is_digits(frac);
}

Calculator::Symbol Calculator::letter(std::string& str)
{
    char ch = eps[0], s[2] = { ch, 0 };
    const size_t ns = eps.size();
    str = s;

    if (ch == 'e') {
        if (ns == 1) {
            return Symbol::e;
        }

        ch = eps[1];

        if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' || ch == ')' || ch == '%') {
            return Symbol::e;
        } else {
            cont = false;
            set_err(Error::unable_to_identify, ch);
            return Symbol::err;
        }
    }

    if (ch == 'p') {
        if (ns == 1) {
            cont = false;
            set_err(Error::unable_to_identify, ch);
            return Symbol::err;
        }

        ch = eps[1];

        if (ch == 'i') {
            if (ns == 2) {
                str = "pi";
                return Symbol::pi;
            }

            ch = eps[2];

            if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' || ch == ')' || ch == '%') {
                str = "pi";
                return Symbol::pi;
            } else {
                cont = false;
                str = "pi";
                s[0] = ch;
                str += s;
                set_err(Error::unable_to_identify, str);
                return Symbol::err;
            }
        } else {
            cont = false;
            s[0] = ch;
            str += s;
            set_err(Error::unable_to_identify, str);
            return Symbol::err;
        }
    }

    if (ns < 5) {
        cont = false;
        set_err(Error::unable_to_identify, eps);
        return Symbol::err;
    }

    str = eps.substr(0, 3);

    if (str == "ln(") {
        str = "ln";
        return Symbol::ln;
    }

    Symbol sym = Symbol::err;
    str = eps.substr(0, 4);

    switch (hash_(str.c_str())) {
    case "sin("_hash:
        str = "sin";
        sym = Symbol::sin;
        break;
    case "cos("_hash:
        str = "cos";
        sym = Symbol::cos;
        break;
    case "tan("_hash:
        str = "tan";
        sym = Symbol::tan;
        break;
    case "cot("_hash:
        str = "cot";
        sym = Symbol::cot;
        break;
    case "sec("_hash:
        str = "sec";
        sym = Symbol::sec;
        break;
    case "csc("_hash:
        str = "csc";
        sym = Symbol::csc;
        break;
    case "log("_hash:
        str = "log";
        sym = Symbol::log;
        break;
    case "abs("_hash:
        str = "abs";
        sym = Symbol::abs;
        break;
    case "exp("_hash:
        str = "exp";
        sym = Symbol::exp;
        break;
    case "fix("_hash:
        str = "fix";
        sym = Symbol::fix;
        break;
    case "sum("_hash:
        str = "sum";
        sym = Symbol::sum;
        break;
    case "min("_hash:
        str = "min";
        sym = Symbol::min;
        break;
    case "max("_hash:
        str = "max";
        sym = Symbol::max;
        break;
    case "rem("_hash:
        str = "rem";
        sym = Symbol::rem;
        break;
    default:
        break;
    }

    if (sym != Symbol::err) {
        return sym;
    }

    if (ns < 7) {
        cont = false;
        set_err(Error::unable_to_identify, eps);
        return Symbol::err;
    }

    str = eps.substr(0, 5);

    switch (hash_(str.c_str())) {
    case "sqrt("_hash:
        str = "sqrt";
        sym = Symbol::sqrt;
        break;
    case "cbrt("_hash:
        str = "cbrt";
        sym = Symbol::cbrt;
        break;
    case "asin("_hash:
        str = "asin";
        sym = Symbol::asin;
        break;
    case "acos("_hash:
        str = "acos";
        sym = Symbol::acos;
        break;
    case "atan("_hash:
        str = "atan";
        sym = Symbol::atan;
        break;
    case "ceil("_hash:
        str = "ceil";
        sym = Symbol::ceil;
        break;
    case "aver("_hash:
        str = "aver";
        sym = Symbol::aver;
        break;
    case "log2("_hash:
        str = "log2";
        sym = Symbol::log2;
        break;
    case "sign("_hash:
        str = "sign";
        sym = Symbol::sign;
        break;
    default:
        break;
    }

    if (sym != Symbol::err) {
        return sym;
    }

    if (ns < 8) {
        cont = false;
        set_err(Error::unable_to_identify, eps);
        return Symbol::err;
    }

    str = eps.substr(0, 6);
    switch (hash_(str.c_str())) {
    case "floor("_hash:
        str = "floor";
        sym = Symbol::floor;
        break;
    case "round("_hash:
        str = "round";
        sym = Symbol::round;
        break;
    case "log10("_hash:
        str = "log10";
        sym = Symbol::log10;
        break;
    default:
        break;
    }

    return sym;
}

void Calculator::remove(std::string& str)
{
    const size_t ns = str.size();
    const size_t ne = eps.size();
    if (ns == ne) {
        eps = "";
        return;
    }
    eps = eps.substr(ns, ne - ns);
}

void Calculator::apply(Symbol sym, std::vector<real>& val,
    std::vector<Symbol>& sign, std::string& str, real& rs)
{
    real v = 0;
    switch (sym) {
    case Symbol::digit:
        v = stor(str);
        apply(val, sign, v);
        break;
    case Symbol::e:
        v = e;
        apply(val, sign, v);
        break;
    case Symbol::pi:
        v = pi;
        apply(val, sign, v);
        break;
    case Symbol::lbrac:
        ++call;
        rs = this->calculate();
        apply_last(val, sign, rs);
        break;
    case Symbol::rbrac:
        --call;
        rs = calcall(val, sign);
        break;
    case Symbol::sum:
        sum = true;
        sign.push_back(sym);
        break;
    case Symbol::aver:
        aver = true;
        sign.push_back(sym);
        break;
    case Symbol::log:
        this->log = true;
        sign.push_back(sym);
        break;
    case Symbol::min:
        min = true;
        sign.push_back(sym);
        break;
    case Symbol::max:
        max = true;
        sign.push_back(sym);
        break;
    case Symbol::rem:
        rem = true;
        sign.push_back(sym);
        break;
    default:
        sign.push_back(sym);
        break;
    }
}

void Calculator::apply(std::vector<real>& val, std::vector<Symbol>& sign, real v)
{
    if (sign.size() == 0) {
        val.push_back(v);
        return;
    }

    if (val.size() == 0) {
        if (sign.back() == Symbol::sub) {
            sign.pop_back();
            val.push_back(-v);
            return;
        } else {
            cont = false;
        }
    }

    real v2;
    switch (sign.back()) {
    case Symbol::mult:
        v2 = val.back();
        val.pop_back();
        sign.pop_back();
        val.push_back(v * v2);
        break;
    case Symbol::div:
        if (v == 0) {
            cont = false;
            set_err(Error::divide_zero, "");
        }
        v2 = val.back();
        val.pop_back();
        sign.pop_back();
        val.push_back(v2 / v);
        break;
    case Symbol::power:
        v2 = val.back();
        val.pop_back();
        sign.pop_back();
        val.push_back(powl(v2, v));
        break;
    case Symbol::mod:
        if ((size_t)v == 0) {
            cont = false;
            set_err(Error::divide_zero, "");
        }
        v2 = val.back();
        val.pop_back();
        sign.pop_back();
        val.push_back((size_t)v2 % (size_t)v);
        break;
    // case Symbol::sub:
    //     sign[sign.size() - 1] = Symbol::add;
    //     val.push_back(-v);
    //     break;
    default:
        val.push_back(v);
        break;
    }
}

real Calculator::calcall(std::vector<real>& val, std::vector<Symbol>& sign)
{
    const size_t nval = val.size();

    if (sign.size() == 0) {
        if (nval == 1) {
            return val.back();
        } else {
            set_err(Error::expression_error, "");
            return 0;
        }
    }
    real v1 = 0, v2 = 0;

    if (this->log) {
        if ((nval != 2) && (sign.size() != 1)) {
            set_err(Error::expression_error);
            return 0;
        }
        return log10l(val[1]) / log10l(val[0]);
    }

    if (this->rem) {
        if ((nval != 2) && (sign.size() != 1)) {
            set_err(Error::expression_error);
            return 0;
        }
        if (val[1] == 0) {
            set_err(Error::divide_zero);
            return 0;
        }
        return (long long)val[0] / (long long)val[1];
    }

    if (sum || aver) {
        if (sign.size() != nval - 1) {
            set_err(Error::expression_error, "");
            return 0;
        }
        v1 = 0;
        for (auto& i : val) {
            v1 += i;
        }
        if (sum) {
            return v1;
        }
        if (aver) {
            return v1 / nval;
        }
    }

    if (min || max) {
        if (sign.size() != nval - 1) {
            set_err(Error::expression_error, "");
            return 0;
        }
        v1 = v2 = val[0];
        for (auto& i : val) {
            if (v1 > i) {
                v1 = i;
            }
            if (v2 < i) {
                v2 = i;
            }
        }
        if (min) {
            return v1;
        }
        if (max) {
            return v2;
        }
    }

    if (sign.size() != nval - 1) {
            set_err(Error::expression_error, "");
            return 0;
    }

    for(size_t i=0; i<sign.size();++i){
        v1=val[i];
        v2=val[i+1];
        switch (sign[i])
        {
        case Symbol::add:
            val[i+1]=v1+v2;
            break;
        case Symbol::sub:
            val[i+1]=v1-v2;
            break;
        default:
            break;
        }
    }

    /*
    do {
        switch (sign.front()) {
        case Symbol::add:
            if (nval < 2) {
                set_err(Error::expression_error, "");
                return 0;
            }
            v1 = val.front();
            val.pop_back();
            v2 = val.front();
            val.pop_back();
            val.push_back(v1 + v2);
            break;
        case Symbol::sub:
            if (nval < 2) {
                set_err(Error::expression_error, "");
                return 0;
            }
            v1 = val.back();
            val.pop_back();
            v2 = val.back();
            val.pop_back();
            val.push_back(v2 - v1);
            break;
        default:
            set_err(Error::expression_error, "");
            break;
        }
        sign.pop_back();
    } while (sign.size() != 0);
    */
    return val.back();
}

void Calculator::apply_last(std::vector<real>& val, std::vector<Symbol>& sign, real& rs)
{
    if (sign.size() == 0) {
        return;
    }
    switch (sign.back()) {
    case Symbol::power:
        if (val.size() == 0) {
            set_err(Error::expression_error, "");
            return;
        }
        sign.pop_back();
        val[val.size() - 1] = powl(val.back(), rs);
        break;
    case Symbol::sin:
        if (!radian) {
            rs = to_radian(rs);
        }
        sign.pop_back();
        val.push_back(sinl(rs));
        break;
    case Symbol::cos:
        if (!radian) {
            rs = to_radian(rs);
        }
        sign.pop_back();
        val.push_back(cosl(rs));
        break;
    case Symbol::tan:
        if (!radian) {
            rs = to_radian(rs);
        }
        sign.pop_back();
        val.push_back(tanl(rs));
        break;
    case Symbol::cot:
        if (!radian) {
            rs = to_radian(rs);
        }
        sign.pop_back();
        val.push_back((real)1 / tanl(rs));
        break;
    case Symbol::sec:
        if (!radian) {
            rs = to_radian(rs);
        }
        sign.pop_back();
        val.push_back((real)1 / cosl(rs));
        break;
    case Symbol::csc:
        if (!radian) {
            rs = to_radian(rs);
        }
        sign.pop_back();
        val.push_back((real)1 / sinl(rs));
        break;
    case Symbol::exp:
        sign.pop_back();
        val.push_back(expl(rs));
        break;
    case Symbol::asin:
        sign.pop_back();
        rs = asinl(rs);
        if (!radian) {
            rs = to_angle(rs);
        }
        val.push_back(rs);
        break;
    case Symbol::acos:
        sign.pop_back();
        rs = acosl(rs);
        if (!radian) {
            rs = to_angle(rs);
        }
        val.push_back(rs);
        break;
    case Symbol::atan:
        sign.pop_back();
        rs = atanl(rs);
        if (!radian) {
            rs = to_angle(rs);
        }
        val.push_back(rs);
        break;
    case Symbol::ln:
        sign.pop_back();
        val.push_back(logl(rs));
        break;
    case Symbol::log:
        sign.pop_back();
        val.push_back(rs);
        this->log = false;
        break;
    case Symbol::sqrt:
        sign.pop_back();
        val.push_back(sqrtl(rs));
        break;
    case Symbol::abs:
        sign.pop_back();
        val.push_back(fabsl(rs));
        break;
    case Symbol::cbrt:
        sign.pop_back();
        val.push_back(cbrtl(rs));
        break;
    case Symbol::floor:
        sign.pop_back();
        val.push_back(floorl(rs));
        break;
    case Symbol::fix:
        sign.pop_back();
        val.push_back((long long)rs);
        break;
    case Symbol::ceil:
        sign.pop_back();
        val.push_back(ceill(rs));
        break;
    case Symbol::round:
        sign.pop_back();
        val.push_back(roundl(rs));
        break;
    case Symbol::sum:
        sign.pop_back();
        val.push_back(rs);
        sum = false;
        break;
    case Symbol::aver:
        sign.pop_back();
        val.push_back(rs);
        aver = false;
        break;
    case Symbol::log10:
        sign.pop_back();
        val.push_back(log10l(rs));
        break;
    case Symbol::log2:
        sign.pop_back();
        val.push_back(log2l(rs));
        break;
    case Symbol::max:
        sign.pop_back();
        val.push_back(rs);
        max = false;
        break;
    case Symbol::min:
        sign.pop_back();
        val.push_back(rs);
        min = false;
        break;
    case Symbol::rem:
        sign.pop_back();
        val.push_back(rs);
        rem = false;
        break;
    case Symbol::sign:
        sign.pop_back();
        if (rs > 0) {
            rs = 1;
        } else if (rs < 0) {
            rs = -1;
        } else {
            rs = 0;
        }
        val.push_back(rs);
        break;
    default:
        apply(val, sign, rs);
        break;
    }
}

bool Calculator::error(std::string& err)
{
    if (call != 0) {
        set_err(Error::expression_error, "");
    }
    err = this->err;
    return cont;
}

void Calculator::set_angle(bool radn)
{
    radian = radn;
}
}
  • strcase.h
/* using the string to the switch
 * writen by Liangjin Song on 20200210
*/
#ifndef STRCASE_H
#define STRCASE_H
#include <cstdint>
namespace slj {
typedef std::uint64_t hash_t;
constexpr hash_t prime = 0x100000001B3ull;
constexpr hash_t basis = 0xCBF29CE484222325ull;

hash_t hash_(char const* str);

constexpr hash_t hash_compile_time(char const* str, hash_t last_value = basis)
{
    return *str ? hash_compile_time(str + 1,
                      (*str ^ last_value) * prime)
                : last_value;
}

constexpr hash_t operator"" _hash(char const* p, size_t)
{
    return hash_compile_time(p);
}
}
#endif  // STRCASE_H
  • strcash.cpp
#include "strcase.h"
namespace slj {
hash_t hash_(char const* str)
{
    hash_t ret{ basis };
    while (*str) {
        ret ^= *str;
        ret *= prime;
        str++;
    }
    return ret;
}
}
相关标签: C&C++ c++